KMP算法实战
相关注意事项:这里求的next数组和王道上的不太一样,此处的next数组其实是prefix_table,prefix_table[i]+1=next[i]
代码
#include<iostream>
#include<string>
using namespace std;
int* get_next(string patten, int *next);
int KMP(string S, string patten, int *next,int pos);
int main() {
string patten, S;
cin >> S;
cin >> patten;
int *next = new int[patten.length()];
get_next(patten, next);
cout << KMP(S, patten, next, 0) << endl;
}
int KMP(string S, string patten, int *next,int pos) {
int i = pos;
int j = 0;
while (i < S.length()) {
if (j==-1||S[i] == patten[j]) {
i++;
j++;
}
else {
j = next[j];
}
if (j == patten.length()) {
return i - j;//若想存放多个匹配成功地字符串索引,则用vector容器存
}
}
}
/*j是已匹配前缀的下一位,i是已匹配后缀的下一位
若i和j相等,则next[i+1]=j+1;
若i和j不相等,则j=next[j]向前回溯,边回溯边看是否和
i对应的字母相等,若一直不相等则回溯到j=-1
*/
int* get_next(string patten, int *next) {
int i=1, j=0;
next[0] = -1;
next[1] = 0;
while(i+1<patten.length()){
if (j==-1||patten[j] == patten[i]) {
next[i + 1] = j + 1;
i++;
j++;
}
else {
j = next[j];
}
}
return next;
}