POJ3461Oulipo

来源:互联网 发布:淘宝店铺怎么激活 编辑:程序博客网 时间:2024/05/29 09:59

#include <stdio.h>#include <string.h>#define max 1000005char a[max/100],b[max];int next[max];int n,m;void get_next(){int i,j;i=0;  j=-1;next[0]=-1;while(i<n)//注意这里是i<n不是i<n-1;因为要记录整个字符串中前缀和后缀的最大匹配数{          //下面要用到当匹配结束后,next[j]所回到的位置if(j==-1 || a[i]==a[j]){i++;  j++;   next[i]=j;}elsej=next[j];}}int kmp(){get_next();int i,j,sum=0;i=j=0;while(i<m){if(j==-1 || a[j]==b[i]){i++; j++;}elsej=next[j];if(j==n)//常规KMP算法不同的是这里。{sum++;j=next[j];//重点注意,这里是为了回到当匹配完后,next[j]应该回到的位置}             //例: a="aza" b="azazaza" 第一次结束后,next[j]应该所指的位置为a中的‘z’,然后继续匹配}return sum;}int main(){int t;scanf("%d",&t);while(t--){memset(a,0,sizeof(a));memset(b,0,sizeof(b));scanf("%s%s",a,b);     n=strlen(a);     m=strlen(b);int k=kmp();printf("%d\n",k);}return 0;}


题目链接:http://poj.org/problem?id=3461

题意: 输入两字符串str1,str2,输出str1在str2中出现的次数。


解题思路:首先想到要用KMP算法,例如str1="aza‘  str2=“azazaza”   则次数为3.    因为第一次匹配完子串,再次开始时并不是从子串最后一位匹配的主串位置的下一位开始。而是从子串第一位所对应的主串的位置下一位开始匹配。  如上例:第一次匹配完后,再次匹配是从str2的第二个字母z开始匹配。

0 0