【字符串处理】【RQNOJ】自然的谜语

 

题目描述

题目描述
给出两个字符串 S1、S2,判断 S1 在 S2 中出现了多少次,并输出每次出现的偏移量。

数据规模
对于 50% 的数据,S1 和 S2 的长度均小于 100。
对于 100% 的数据,S1 和 S2 的长度均小于 100000,且 S1 的长度不超过 S2 的长度。

输入格式

两个,分别为字符串 S1 和 S2。

输出格式

如果 S1 没有在 S2 中出现,则输出“There must be something wrong.”(注意大小写,符号为半角,建议直接复制)。
如果 S1 在 S2 中出现了,则第一行输出一个数为 S1 在 S2 中出现的次数 n,后跟 n 行,分别为这 n 次出现的偏移量(即 S1 首字母对应于 S2 中的位置)。

样例输入

aba

ababababab

样例输出

4

1

3

5

7

三维状态图像

 


 

必会算法KMP,包括三个主要的过程。计算f[x]函数,f[x]改进,进行匹配。

#include #include #define maxn 100010 int f[maxn]; char s1[maxn],s2[maxn]; int ans[maxn],tot; int n,m; void init() { int k=0; for (int i=2;i<=m;++i) { while (k>0&&s2[k+1]!=s2[i]) k=f[k]; if (s2[k+1]==s2[i]) ++k; f[i]=k; } } int main() { scanf("%s%s",s2,s1); m=strlen(s2); n=strlen(s1); for (int i=m;i>=1;--i) s2[i]=s2[i-1]; s2[0]='/0'; for (int i=n;i>=1;--i) s1[i]=s1[i-1]; s1[0]='/0'; int k=0; init(); for (int i=1;i<=m;++i) { k=f[i]; while ((k>0)&&(s2[k+1]==s2[i+1])) k=f[k]; f[i]=k; } k=0; for (int i=1;i<=n;++i) { while ((k>0)&&(s2[k+1]!=s1[i])) k=f[k]; if (s2[k+1]==s1[i]) ++k; if (k==m) { ++tot; ans[tot]=i-m+1; } } if (!tot) printf("There must be something wrong./n"); else { printf("%d/n",tot); for (int i=1;i<=tot;++i) printf("%d/n",ans[i]); } return 0; } 

 

 

你可能感兴趣的:(字符串处理,RQNOJ,算法)