nyoj 327 亲和串 【kmp(好题)】
2015-09-03 15:21
393 查看
亲和串
时间限制:1000 ms | 内存限制:65535 KB[align=center]难度:3[/align]
描述 最近zyc遇到了一个很棘手的问题:判断亲和串,以前判断亲和串的时候直接可以看出来,但现在不同了,现在给出的两字符串都非常的大,看的zyc头都晕了。于是zyc希望大家能帮他想一个办法来快速判断亲和串。亲和串定义:给定两个字符串s1和s2,如果能通过s1循环移动,使s2包含在s1中,那么我们就说s2是s1的亲和串。
输入本题有多组测试数据,每组数据的第一行包含输入字符串s1,第二行包含输入字符串s2,s1与s2的长度均小于100000。输出如果s2是s1的亲和串,则输出"yes",反之,输出"no"。每组测试的输出占一行。样例输入
AABCD CDAA ASD ASDF
样例输出
yes no
来源hdu上传者路过这
思路:
刚开始没有看懂题意!实际上这还是让求是否有匹配字符串,但是这个题中的被匹配对象一直在发生变化,将整体往后移动,将最后一个放到最前面,这时候,我们可以巧妙的将这个字符串看成一个环状的字符串,然后将第二个字符串与这个环状的字符串进行匹配,但是如果是环状的字符串匹配我们又没有学过,所以我们可以把它看成一个两个字符串拼接成的一个字符串,但是由于数组过大,拼接的话会溢出,所以,就用这个类似滚动数组的办法将下标进行取余,得到的正好是对应的字符,最终遍历所有的字符如果匹配成功输出“yes”,否则输出“no”!
代码:
#include <stdio.h> #include <string.h> char a[100005]; char b[100005]; int p[100005]; int lena,lenb; void getp() { int i=0,j=-1; p[0]=-1; while(i<lenb) { if(j==-1||b[i]==b[j]) { i++;j++; p[i]=j; } else j=p[j]; } } void kmp() { getp(); int i=0,j=0; while(i<2*lena)//这一点要注意,将数组a的下标考虑成a的长度的二倍了! { if(j==-1||a[i%lena]==b[j])//因为它后面的字符就是将前面的字符平移了lena的长度 {//所以,直接对下标取余得到的就是所要的字符! i++;j++; if(j==lenb) { printf("yes\n"); return; } } else j=p[j]; } printf("no\n"); } int main() { while(scanf("%s",a)!=EOF) { scanf("%s",b); lena=strlen(a); lenb=strlen(b); kmp(); } return 0; }
相关文章推荐
- 关于Android开发中Java对象序列化的一次测试
- Stretch Key Dimensions to See What Breaks
- 频道发布与消息订阅
- Objective-C 【This is ARC】
- KVO实现机制 & 如何自己动手实现 KVO
- Objective-C 【This is ARC】
- E. Bear and Drawing
- ubifs烧写遇到《UBI error: ubi_io_read: error -1 while reading 64 bytes from PEB》
- sass 安装使用杂记
- 给内联元素设置宽高的几种方式
- Effective C++ 改善程序与设计的55个具体做法 二周目笔记01
- Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)
- Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)
- Oracle行转列和列转行
- python编码问题 decode('unicode-escape')
- 最大公约数和
- HDU 4596 Yet another end of the world(解一阶不定方程)
- HDU5053-the Sum of Cube-2014 ACM/ICPC Asia Regional Shanghai Online(水题求立方和)
- 编写第一个程序HelloWorld(你好,世界)
- How Not to Crash #3: NSNotification通知引起的崩溃