HDU-2087 剪花布条 (KMP)

题意:给出两个字符串,求其中一个在另一个中出现的次数(不可重复匹配)

思路:由于是不可重复的,所以相对于POJ-3461 (允许重复匹配),kmp的移动要进行修改,此时就将子串的下标置为0重新开始匹配即可

完整代码:


#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 1000050
char a[maxn],b[maxn];
int nex[maxn];
int len2,len1; 
void getnext(){
	int i= 0,j =-1;//i为副串的序号 
	nex[i] = j;
	while(i<len2){
		if(j==-1||b[i]==b[j]){
			nex[++i] =++j;
		}else j = nex[j];
	}
}
int kmp(){
	int ans = 0;
	int i= 0,j=0;
	if(len1 == 1 && len1 == 1)
    {
       return  (a[0] == b[0])?1:0;
    }
	getnext();
	for(i=0;i<len1;i++)
	{
		while(j>0&&a[i]!=b[j])
			j=nex[j];
		if(a[i]==b[j])	j++;
		if(j==len2)
		{
			ans++;
			j = 0;
		}
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	while(scanf("%s",&a)){	
		if(a[0]=='#') break;
		scanf("%s",&b);
		len1 = strlen(a);
		len2 = strlen(b);
		int ans = kmp();
		cout<<ans<<endl;
	}
} 
 
原文地址:https://www.cnblogs.com/Tianwell/p/11208627.html