kmp算法

kmp算法

本人理解敲出来的,有些长,如果想要理解请认真看完
模式串的next
那么如何进行匹配呢,若文本串str1为aabaaaabaaf,模式串str2为aabaaf
上面求出来aabaaf的next表为 010120
指针 i = 0, j = 0 (i为文本串指针, j为模式串指针)

kmp比较流程
如果想要搞懂一定要,一定要手写一下这个比较流程你会很清晰。

next数组,并不需要求出所有的子串,我们可以看到aabaa
前缀[a,aa,aab,aaba]
后缀[a,aa,baa,abaa]
最大相符的是aa,但前面a也相符,所以最大相符前面的必然相符,就是一个循环对半对比,知道不相等就退出,不相等的前一个位置的子串数目就是最大个数,比较次数为子串索引max / 2

比较时候为了方便每个位置的前缀值=前一个位置,第一个位置为-1
所以:当j = -1时候代表该元素没有办法移动到别的前缀,那么i++,j++(j=0)即下一个位置的元素与模式串第一个元素比较
当j不等于-1时候,i和j上的元素不相等则,j改为前缀值进行比较,相等i++,j++
如图
kmp

int getlength(T& array) {
	return (sizeof(array) / sizeof(array[0]));
}
int kmp(string str1, string str2) {
	int n1 = str1.size();
	int n2 = str2.size();
	int* next = new int[n2];
	next[0] = -1;
	//获取前缀表
	for (int i = 0; i < n2-1; i++) {
		int z = i; int x = 0;
		int num = (i + 1) / 2;
		for (int j = 0; j < num; j++) {
			if (str2[j] != str2[z]) {
				break;
			}
			else {
				z--;
				x++;
			}
		}
		next[i+1] = x;
	}
	for (int i = 0; i < n2; i++) {
		cout << next[i];
	}
	//kmp
	int i = 0; int j = 0;
	while (i < n1 && j < n2) {
		if (j == -1 || str1[i] == str2[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
	}
	if (j >= n2) {//匹配成功,返回子串的位置
		return i - n2;
	}
	return -1;
}
int main() {
	string str1, str2;
	str1 = "anjabaabaafxdf";
	str2 = "aabaaf";
	cout << endl << kmp(str1, str2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值