#include<iostream> #include<string> #include<vector> using namespace std; void get_next(const char * subStr,vector<int>&next ) { next[0] = strlen(subStr); next[1]= 0; next[2]=1; int i = 3; int j =2; while(j < strlen(subStr)) { if(subStr[i-1]== subStr[next[i-1]] ) { next[i]=next[i-1]+1; } else { next[i]=next[i-1]; } i++; j++; } } int index_KMP(string s,string t) { int i =0; int j =0; vector<string>sTemp(s.length()+1); vector<string>tTemp(t.length()+1); while( i < s.length()) { sTemp[i+1]=s[i]; i++; } sTemp[0]= s.length(); while(j <t.length()) { tTemp[j+1]=t[j]; j++; } tTemp[0]=t.length(); i=1; j=1; vector<int>next(t.length()+1); get_next(t.c_str(),next); int slen = s.length(); int tLen= t.length(); while(i <= slen && j<= tLen) { if(sTemp[i] == tTemp[j]) { i++; j++; } else if(sTemp[i] != tTemp[j] && 0 != j) { j=next[j]; } else if(0 == j) { i++; j++; } } if(j >tLen) { return i-tLen; } return 0; } int main(int _args,char *arg[]) { string s ="abcdabcbcabcabc"; string t="abcabc"; cout<<"s ="<<s<<endl; cout<<"t ="<<t<<endl; int nResult = index_KMP(s,t); if(0 == nResult) cout<<"匹配失败"<<endl; else cout<<"在第"<<nResult<<"找到匹配项"<<endl; return 0; } // 上面的代码是位序为1的kmp KMP算法中的next函数解析: 位序 1 2 3 4 5 6 模式串 a b c a b c next值 0 1 1 1 2 3 第一位的next值为0,第二位的next值为1 以上是位序从1开始: 第三位的求解: 看前一位为2,模式串为b与对应的next值为1,将第二位的模式串与第一位的模式串比较,不等则为1, 若相等则在第二位的next值上加1 位序从0开始: 位序 0 1 2 3 4 5 模式串 a b c a b c next值 -1 0 0 0 1 2 默认第一位和第二位为:-1,0 第三位: 看第二位,第二位的模式串为b与对应的next值为0,将第二位的模式串与第一位的模式串比较,不等则为0 第四位: 看第三位,第三位的模式串为c与对应的next值为0,将第三位的模式串与第一位的模式串比较,不等则为0 第六位: 看第5位,第四位的模式串为a,next值为0,发现a与第一位模式串比较相等则next=0+1;将第五位的模式串next值加1 以上next值分两种情况求解 再就是index_KMP()函数的解析: 匹配过程: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 源串为:"a b c d a b c b c a b c a b c " 变量指针为i j 1 2 3 4 5 6 匹配串为:" a b c a b c " 变量指针为j next[j] 0 1 1 1 2 3 初始化 i=1,j=1 1.当i=4 , j=4时,匹配不相等,j=next[j] 通过函数get_next可求得next值,j=1,i值不发生变化 2.i=4,j=1,时,源串为d,模式串为a 不匹配,则j=next[j]=0,当j=0时,i++,j++ 3.i=5,j=1时,源串a 与模式串a相等,i++,j++同理 比较到i=8,j=4时,源字符为b,模式串为a不相等,j=next[4]=1,i值不变 4.i=8,j=1时,源串b != 模式串a ,j=next[j]=0 ,i++,j++ 5.i=9 ,j=1, c != a,j=next[j]=0,i++,j++ 6.i=10,j=1, a=a,i++,j++,一直到i=15,j=6 仍然相等,i++,j++, i=16> 源串大小长度=15,j=7>模式串大小长度=6退出循环 函数返回值为 i-模式串长度=6 = 16-6=10; 结束 //现在恶补数据结构,看了2天才写出来,只知道怎么实现,但是具体原理还没弄透,先写到这,方便以后学习
(KMP) alogrithm 实现
最新推荐文章于 2024-07-08 22:12:26 发布