码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法

时间:2019-08-29 20:04:57      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:height   dash   include   main   特点   自我   code   回文   strong   

KMP算法是一种高效的字符串匹配算法。

KMP算法的特点是给定一个主串,给定一个匹配串,问匹配串在主串中出现的次数,匹配串在主串中出现的位置等。

首先我们先看一种暴力的方法——按位对比,若匹配失败从头再来。

我们用两个指针,一个指针i指在主串,一个指针j指在匹配串,

如果s1[i+1]!=s2[j+1],根据暴力的思想就从头开始匹配,i=匹配开头+1,j=1;

显然这么不优,这样太过暴力,KMP算法的核心思想就是对于匹配失败后j的位置做一个优化。

我们来看下面这种情况

s1=‘aabaac‘ s2=‘aabaabaac‘

当i=j=5的时候 显然s[i+1]!=s[j+1];

技术图片

 

 

 若是按照原来暴力的想法此时应把匹配串的j调整为1,i调整为匹配开头+1;

但我们发现匹配串有个性质就是部分回文,s1的前五个元素为aabaa,此时如果把i++,j=3便可继续匹配。

利用这个性质,我们可以对原方法有一个很大的优化即——KMP算法。

KMP的核心是预处理一个fail数组即确定匹配失败后,j指针应该调整到哪个位置。

预处理的方法就是自我匹配,显然fail[1]=0;

 

1 int s2_len=strlen(s2+1);
2 int j=1;
3 for(int i=1;i<=s2_len;i++)
4 {
5     while(s[i]!=s[j+1]&&j>0) j=fail[j];
6     if(s[i]==s[j+1]) j++;
7     fail[i]=j;
8 }

 

然后匹配匹配串与主串即可。

全部代码洛谷P3375

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int kmp[1000005],n,m;
 9 char s1[1000005],s2[1000005];
10 
11 int main()
12 {
13     scanf("%s%s",s1+1,s2+1);
14     n=strlen(s1+1);
15     m=strlen(s2+1);
16     kmp[1]=0;
17     int j=0;
18     for(int i=2;i<=m;i++)
19     {
20         while(j&&s2[j+1]!=s2[i]) j=kmp[j];
21         if(s2[j+1]==s2[i]) j++;
22         kmp[i]=j;
23     }
24     j=0;
25     for(int i=1;i<=n;i++)
26     {
27         while(j&&s1[i]!=s2[j+1]) j=kmp[j];
28         if(s2[j+1]==s1[i]) j++;
29         if(j==m)
30         {
31             printf("%d\n",i-m+1);
32             j=kmp[j];
33         }
34     }
35     for(int i=1;i<=m;i++)
36        printf("%d ",kmp[i]);
37     return 0; 
38 }

 

KMP算法

标签:height   dash   include   main   特点   自我   code   回文   strong   

原文地址:https://www.cnblogs.com/Hoyoak/p/11431556.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!