版权声明:iQXQZX https://blog.csdn.net/Cherishlife_/article/details/85245676
例题
学骚话
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
众所周知,青春期猪头少年梓川咲太骚话连篇。
这可让众多网友羡慕不已,于是观众们纷纷尊称其为师傅,更有甚者已经开始模仿师傅学习了。
现在给你两行字符,第一行是师傅梓川咲太的正宗骚话,第二行是某位**网友的模仿。
请问这位网友的骚话完成度是多少?
骚话完成度是指该骚话在原版中的出现次数,在原版中出现时可重叠。
Input
输入包含多组数据。
每组数据由两行字符串构成,分别表示猪头少年的正宗骚话和网友的模仿。
字符串长度均在1000000以内。
Output
输出X的最大长度,占一行
Sample Input
abababababa aba
Sample Output
5
Hint
Source
行走的二叉树
#include <bits/stdc++.h>
using namespace std;
int nextt[1000005];
int ans;
void get_next(char str2[]) // 构建前缀表
{
int len = strlen(str2);
nextt[0] = -1;
int j = -1, i = 0;
while (i < len)
{
if (j == -1 || str2[i] == str2[j])
{
i++;
j++;
nextt[i] = j;
}
else
j = nextt[j]; // 失配回溯
}
}
void kmp(char str1[], char str2[])
{
get_next(str2);
int len1 = strlen(str1), len2 = strlen(str2);
int i = 0, j = 0;
while (i < len1 && j <= len2)
{
if (j == 0 || str1[i] == str2[j])
{
i++;
j++;
}
else
j = nextt[j]; // 失配回溯
if (j == len2) // j==len2说明匹配上 然后往后挪len2-1个单位 匹配下一次
{
ans++;
j = 0;
i -= len2 - 1;
}
}
}
int main()
{
char str1[1000005], str2[1000005];
while (~scanf("%s", str1))
{
scanf("%s", str2);
ans = 0;
kmp(str1, str2);
printf("%d\n", ans);
}
return 0;
}