您的位置:首页 > 其它

POJ 3461 Oulipo(字符串匹配,KMP算法)

2013-09-23 21:50 405 查看
题意:给出几组数据,每组有字符串W和T,问你W在T中出现几次。

思路:字符串长度很大,用KMP算法。

  一开始写的是:调用KMP算法查找W在T中是否匹配,若匹配,则个数+1。则接下来T的索引移动相应的距离,再调用函数判断T接下来的序列中是否存在W。

         如果不能匹配,则终止。

  结果,这样超时了。。。估计是调用函数上面花费了些时间。

  后来直接在函数中记录出现的个数,这样就不超时了。

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
const int maxT=1000010;
const int maxW=10010;
char w[maxW],t[maxT];
int suffix[maxW];//suffix[i]=k:表示P中前i个字符中,后缀与前缀间的最长匹配子串的长度。

void dealSuffix(int m){
memset(suffix,0,sizeof(suffix));
suffix[0]=-1;
suffix[1]=0;
int k=0;
for(int i=2;i<=m;i++){
while(k>=0 && w[k]!=w[i-1])
k=suffix[k];
suffix[i]=++k;
}
}

//m为W字符串的长度
int match(int n,int m){
int i=0,j=0;  //i为T中字符的下标,j为W中字符的下标
int cnt=0;   //统计W字符串在T字符串中出现的次数
while(i<=n-1){
if(j<0){
i++;
j=0;
}
if(t[i]==w[j]){
i++;
j++;
}
else if(j>=0){
j=suffix[j]; //当j=0的时候,suffix[0]=-1,这样j就会小于0,所以一开始有判断j是否小于0
}

//W在T中找到匹配
if(j==m){
cnt++;
j=suffix[j];
}
}
return cnt;
}
int main()
{
int n,lw,lt;
scanf("%d",&n);
getchar(); //用gets的话,这里要写个getchar()
while(n--){
gets(w);
gets(t);
lw=strlen(w);  //W字符串的长度
lt=strlen(t);  //T字符串的长度
dealSuffix(lw);
int ans=match(lt,lw);
printf("%d\n",ans);
}

return 0;
}


下面是照搬算法导论上的代码:

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
const int maxT=1000010;
const int maxW=10010;
char w[maxW],t[maxT];
int suffix[maxW];//suffix[i]=k:表示P中前i个字符中,后缀与前缀间的最长匹配子串的长度。

//m为w字符串的长度
void getSuffix(int m){
memset(suffix,0,sizeof(suffix));
suffix[1]=0;
int k=0;
for(int i=2;i<=m;i++){
while(k>0 && w[k]!=w[i-1])
k=suffix[k];
if(w[k]==w[i-1])
k++;
suffix[i]=k;
}
}
//n为t字符串的长度,m为W字符串的长度
int match(int n,int m){
int k=0,ans=0;
for(int i=0;i<n;i++){
while(k>0 && w[k]!=t[i])
k=suffix[k];
if(w[k]==t[i])
k++;
if(k==m){
ans++;
k=suffix[k];
}
}
return ans;
}
int main()
{
int n,lw,lt;
scanf("%d",&n);
getchar(); //用gets的话,这里要写个getchar()
while(n--){
gets(w);
gets(t);
lw=strlen(w);  //W字符串的长度
lt=strlen(t);  //T字符串的长度
getSuffix(lw);
int ans=match(lt,lw);
printf("%d\n",ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: