其他分享
首页 > 其他分享> > 关于KMP的见解

关于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