0
点赞
收藏
分享

微信扫一扫

字符串模式匹配(KMP)


字符串模式匹配(KMP)

给定一个字符串 text 和一个模式串 pattern,求 pattern 在text 中的出现次数。text 和 pattern 中的字符均为英语大写字母或小写字母。text中不同位置出现的pattern 可重叠。

输入格式:

输入共两行,分别是字符串text 和模式串pattern。

输出格式:

输出一个整数,表示 pattern 在 text 中的出现次数。

输入样例1:

zyzyzyz
zyz

输出样例1:

3

输入样例2:

AABAACAADAABAABA
AABA

输出样例2:

3

数据范围与提示:

1≤text, pattern 的长度 ≤10
6
, text、pattern 仅包含大小写字母。
本题关于KMP算法这一点,我能力有限,无法做出更加详细的解释
点击前往july博客 这道题就是在kmp的基础上,如果找到一个子串后,不要return,先让计数器++,再让i–,即返回到上一个字符,让j=next[j-1],即假设第j个字符失配,然后继续执行相关操作即可.还有一点就是,作者能力有限,不知道为什么一改成优化后的next数组就不对,不优化就对了,如果有谁知道的话,欢迎下方评论指教.

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char s[1000005],p[1000005];
int Next[1000005];
void GetNext(int pLen){
	int k=-1;
	Next[0]=-1;
	int j=0;
	while(j<pLen){
		if(k==-1||p[j]==p[k]){
			j++;
			k++;
			Next[j]=k;
		}else {
			k=Next[k];
		}
	}
}
int KMP(int sLen,int pLen){
	int i=0;
	int j=0;
	int cnt=0;
	while(i<sLen&&j<pLen){
		if(j==-1||s[i]==p[j]){
			i++;
			j++;
		}else{
			j=Next[j];
		}
		if(j==pLen)cnt++,j=Next[j-1],i--;
	}
	return cnt; 
}
int main(){
	int sLen,pLen;
	for(sLen=0;(s[sLen]=getchar())!='\n';sLen++);
	for(pLen=0;(p[pLen]=getchar())!='\n';pLen++);
	GetNext(pLen);
	cout<<KMP(sLen,pLen);
}


举报

相关推荐

0 条评论