KMP算法

Posted 我是小学生1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMP算法相关的知识,希望对你有一定的参考价值。

KMP算法(三个人名字开头字母)

对BF算法进行了改进,省去了一部分没必要的比较,提高了算法的效率。

K,M,P这三个人发现了BF算法中一些模式中遗憾的用于模式匹配的信息,这种信息就是模式匹配中的“部分匹配“的信息。

首先先要理解引入的Next[Size]数组的含义,简单的理解就是一个模式串对应一个Next数组,模式串确定后,也的Next数组也是确定的。

这里要引入我看的一篇博文了,在这里表示感谢!

(孤~影http://www.cnblogs.com/yjiyjige/p/3263858.html

然后具体的实现:

 1 #include <iostream>
 2 #include <string>
 3 #define MaxSize 100
 4 using namespace std;
 5 
 6 void GetNext(string t,int next[])  //由模式串t获取其Next数组
 7 {
 8     int j,k;
 9     j=0;
10     k=-1;
11     next[0]=-1;
12     while (j<t.length()-1)
13     {
14         if (k==-1 || t[j]==t[k])
15         {
16             j++;
17             k++;
18             next[j]=k;
19         }
20         else
21             k=next[k];  //指针回溯到next[k]处,继续比较
22     }
23 }
24 
25 int KmpIndex(string s,string p)
26 {
27     int next[MaxSize],i=0,j=0;
28     GetNext(p,next);
29     while (i<s.length() && j<p.length())
30     {
31         if(j==-1 || s[i]==p[j])
32         {
33             i++;
34             j++;
35         }
36         else
37         {
38             j=next[j];
39             cout<<"回溯到:"<<j<<endl;
40         }
41     }
42     if (j>=p.length())
43     {
44         return i-p.length();
45     }
46     else
47         return 0;
48 
49 }
50 
51 int main()
52 {
53     string s,p; //目标串和模式串
54     int i;
55     int next[MaxSize];
56     cin>>s>>p;
57     GetNext(p,next);
58     cout<<"next数组为:"<<endl;
59     for (i=0;i<100;i++)
60     {
61         if (next[i]>=-1)
62         {
63             cout<<next[i]<<" ";
64         }
65     }
66     cout<<endl;
67     cout<<"KMP算法结果为:"<<KmpIndex(s,p)<<endl;
68     return 0;
69 }
KMP算法的具体实现

改进后的算法和上一个一样,时间复杂度为O(n+m)

改进内容:

s=aaabaaaab,p=aaaab,实际上当我匹配到s[4]!=p[4]时,按照改进前我应该回溯到第二个a,即s[1],实际上是不用的,因为模式中1,2,3,4字符均相等,可以将其next数组中的值都给成和第一个a一样的值,这里是-1,所以改进后效率也有了相应的提高。

 1 #include <iostream>
 2 #include <string>
 3 #define MaxSize 100
 4 using namespace std;
 5 
 6 void GetNext(string s,int next[])
 7 {
 8     int j=0,k=-1;
 9     next[0]=-1;
10     while (j<s.length())
11     {
12         if (k==-1 || s[j]==s[k])
13         {
14             j++;
15             k++;
16             if (s[j]!=s[k])
17             {
18                 next[j]=k;
19             }
20             else
21                 next[j]=next[k];
22         }
23         else
24             k=next[k];
25     }
26 }
27 
28 int KMPIndex1(string s,string p)
29 {
30     int next[MaxSize],i=0,j=0;
31     GetNext(p,next);
32     while (i<s.length() && j<p.length())
33     {
34         if (j==-1 || s[i]==p[j])
35         {
36             i++;
37             j++;
38         }
39         else
40             j=next[j];
41     }
42     if (j>=p.length())
43     {
44         return i-p.length();
45     }
46     else
47         return 0;
48 }
49 
50 int main(){
51     string s,p;
52     cin>>s>>p;
53     cout<<"KMP改进后的算法结果为:"<<KMPIndex1(s,p)<<endl;
54     return 0;
55 }
改进后的KMP算法具体实现

反过头来看之前学过的算法依旧收获很多。

初来乍到,请多关照。(轻喷ㄟ(▔=▔)ㄏ)

以上是关于KMP算法的主要内容,如果未能解决你的问题,请参考以下文章

数据结构—串KMP模式匹配算法

Python ---- KMP(博文推荐+代码)

KMP算法及Python代码

KMP算法及Python代码

图解KMP算法原理及其代码分析

Kmp算法Java代码实现