关于KMP的见解
作者:互联网
#include<iostream>
#include<string>
using namespace std;
const int N = 100;
int judge(string s1, string s2) {
int k = -1;
int j = 0;
int next[N] = { -1 };
int max = 0;
//int x1=0,x2=0;
/*while (l < s2.length()) {
x1 = 0; x2 = 0;
static int a= 2;//a用来记录s2字符串的。a表示前面有几个字符。static防止a一直被初始化
for (int i = 1; i < a;i++) {
if (s2[x2] == s2[i]) {//这样不管在那里的后缀,都可以和第0位进行比较。
x1++;
x2++;
}
}
next[a] = max;
a++; l++;//a++表示
}*/
while (j < s2.length() - 1) {
if (k == -1 || s2[j] == s2[k]) {
k++;
j++;
next[j] = k;
}
else
k = next[k];
}
cout << endl << "next的取值:";
for (int i = 0; i < s2.length(); i++) {
cout << next[i] << ' ';
}
cout << endl;
int i = 0; j = 0;//i是主串,j是查找的字符串
while (s1[i] != '\0') {
if (j == -1) {
i++;
j++;
}
if (s1[i] == s2[j])
{
j++;
i++;
}
else
j = next[j];
if (j== s2.length()-1)//j==匹配字符串长度,说明匹配成功,退出循环就行了。
break;
}
if (j== s2.length()-1)return i - j + 1;
else {
return 0;
}
}
int main() {
cout << "输入主串字符串" << endl;
string s1;
getline(cin, s1);
string s2;
cout << "输入需要查找的字符串" << endl;
getline(cin, s2);
int num = judge(s1, s2);
if (num == 0) {
cout << "未搜到您所查找的字符串" << endl;
}
else
cout << "在第" << num<< "个位置上";
return 0;
}
代码如上,一开始错误的想法写了一个n^2的next数组查值(备注那里),一开始想的以为是查找字符串里有相同的他的回溯的值就可以+1。比如“aaabaa”,我一开始以为他的回溯值是{-1,0,1,2,2,2},就像这个2,我以为中间任意部分有相等就可以加1,这样查找也能找出大部分的值。
但是复杂度明确写的是O(n+m)我怎么想感觉就一个循坏也不能确定next数组的取值范围(因为一开始还想着包括中间部分相等的情况),后来看了看别人的代码,终于知道了,原来这个next回溯值是看你首和尾先要一致,头往后推,尾往前找,这样找到的最大值,个人认为求出next的取值范围,剩下的就很好理解了。
第一次写博客,还是一名在校大二学生,经验不足,如果那里写的有错误或者词语不恰当,敬请理解并帮忙指出,谢谢。
标签:见解,int,s2,next,++,关于,KMP,x2,x1 来源: https://blog.csdn.net/dxgzg/article/details/102768885