hdoj-1686 Oulipo

来源:互联网 发布:企查查软件下载 编辑:程序博客网 时间:2024/06/08 10:17

题目详见链接http://acm.hdu.edu.cn/showproblem.php?pid=1686

kmp相关内容详见链接http://blog.csdn.net/qq_29606781/article/details/47340491

题目大意:求一个字符串在另一个字符串中出现的次数    (是包含不是分割)

#include<cstdio>#include<cstring>#define MAXN 10010char buf[MAXN*100],str[MAXN];//buf主串  str 标准串 int p[MAXN];int len1,len2,ans;void getp()       //求next {    int i=0,j=-1;    p[i]=j;    while(i<len1)    {        if(j==-1||str[i]==str[j])        {            i++,j++;            p[i]=j;        }        else j=p[j];    }     } int kmp() //kmp实现 {    getp();    int i=0,j=0;    ans=0;//*    while(i<len2)    {        if(j==-1||buf[i]==str[j])            i++,j++;                    else j=p[j];        if(j==len1)ans++;    }    return ans;//*}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s%s",str,buf);        len1=strlen(str);        len2=strlen(buf);        printf("%d\n",kmp());//不能写成kmp();                     //        printf("%d\n",kmp())重复执行了kmp     }    return 0;}/*或者 void kmp(){getp();    int i=0,j=0;    while(i<len2)    {        if(j==-1||buf[i]==str[j])            i++,j++;                    else j=p[j];        if(j==len1)ans++;    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {    ans=0;//ans 在开头已经定义  这里无需再定义  否则出错         scanf("%s%s",str,buf);        len1=strlen(str);        len2=strlen(buf);        kmp();        printf("%d\n",ans);    }    return 0;} */

 

0 1 2 3 4 5 6
A Z A Z A Z A
A Z A
0 1 2
 主串中包含3个AZA     标准串前三个刚好能匹配成功  接下来滑动到哪个位置继续匹配呢?即确定他的滑动区间(即next值)

##处  当标准串字母都匹配成功后 第一次匹配结束  i=3,j=3 i<len2=7继续while循环  str[3]不存在 需要移位 j=p[j]=p[3]
需求p[3]的值
#处   i<len1执行while 循环  标准串求第二个A的next后 i++,j++,i = 3,j = 3,p[3]=1
i  0  1  2  3      虽然str[3] 不存在 但是能求出p[3]=1
   A  Z  A
j  -1 0  0  1
所以 j=1  buf[3]与str[1]比较(即 标准串右移 使 buf[3]与str[1] 对齐 )


 

0 0
原创粉丝点击