#include<iostream>
using namespace std;
const int N = 1e3 + 10;
char s1[N], s2[N];
int ne[N];
bool st[N];
int main()
{
cin>>s1 + 1;
while(s1[1] != '#'){
cin>>s2 + 1;
int rv = 0;
int len1 = 0, len2 = 0;
for(int i = 1; i <= N; i ++ ){
if(s1[i] > 32){
len1 ++ ;
}
else if(s1[i] <= 32){
break;
}
}
for(int i = 1; i <= N; i ++ ){
if(s2[i] > 32){
len2 ++ ;
}
else if(s2[i] <= 32){
break;
}
}
//计算前缀数组
for(int i = 2, j = 0; i <= len2; i ++ ){//s[1]的前缀数组为0,所以直接从2开始匹配,从1开始可能会陷入死循环
while(j && s2[i] != s2[j + 1]) j = ne[j];//当p数组和子串不匹配时,子串直接移动到下一次可以和前面部分字符串匹配的位置
if(s2[i] == s2[j + 1]){//当子串数组的下一位和p数组的下一位匹配时,j++代表前缀后缀数组相同部分的长度++;
j ++ ;
}
ne[i] = j;//字符串第i位的kmp值为j;
}
for(int i = 1, j = 0; i <= len1; i ++ ){//当s数组和p数组的下一位不匹配时,p数组直接移动到下一次可以和前面部分字符串匹配的位置
while(j && s1[i] != s2[j + 1] ){//当s数组和p数组的下一位不匹配时,p数组直接移动到下一次可以和前面部分字符串匹配的位置
j = ne[j];
}
if(s1[i] == s2[j + 1] ){//当s数组和p数组匹配时,j++(j此时代表匹配的长度)
j ++ ;
}
if(j == len2){//当匹配的长度等于p字符串的长度时,代表全部匹配成功
rv ++ ;
j = 0;//已经匹配成功一个,s2的指针位置重置,s1的指针位置不变,继续向后遍历
}
}
cout<<rv<<endl;
cin>>s1 + 1;
}
return 0;
}
HDU 剪花布条 题解(KMP模板题)
最新推荐文章于 2022-04-20 23:46:23 发布