loj #10043. 「一本通 2.2 例 1」剪花布条

直接用KMP...

唯一的区别是匹配到的子串不能重叠 所以一次匹配成功后要把j清成0

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char a[100001], b[1001];
int j, next[1001], cnt, lena, lenb;
int KMP(){
	j=0;
	for(int i=1; i<=lena; i++){
		while(j>0 && a[i]!=b[j+1])j=next[j];
		if(a[i]==b[j+1])j++;
		if(j==lenb)cnt++, j=0;
	}
	return cnt;
}
void ycl(){
	j=0;
	memset(next, 0, sizeof(next));
	for(int i=2; i<=lenb; i++){
		while(j>0 && b[i]!=b[j+1])j=next[j];
		if(b[i]==b[j+1])j++;
		next[i]=j;
	}
}
int main(){
	while(1){
		cnt=0;
		cin>>a+1;
		lena=strlen(a+1);
		if(a[1]=='#'&&lena==1)break;
		cin>>b+1;
		lenb=strlen(b+1);
		ycl();
		printf("%d
", KMP());
	}
	return 0;
}
不如吃茶去
原文地址:https://www.cnblogs.com/pushinl/p/9474809.html