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 }
改进后的算法和上一个一样,时间复杂度为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 }
反过头来看之前学过的算法依旧收获很多。
初来乍到,请多关照。(轻喷ㄟ(▔=▔)ㄏ)