您的位置:首页 > 其它

hdoj 1686 Oulipo【kmp】

2015-08-26 21:26 330 查看

Oulipo

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 7753 Accepted Submission(s): 3122



题目大意:给个数 T,表示有T组测试数据;

每个测试用例给两个字符串,第一个字符串的长度L1(1 ≤ |L1| ≤ 10,000),第二个字符串长度L2(1 ≤ |L2| ≤ 1,000,000)

求第一个字符串在第二个字符串中出现的次数,如下例:

[align=left]Sample Input[/align]

3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN


[align=left]Sample Output[/align]

1
3
0


此处先设字符串一为str,字符串二位buf;
传统思路:用str首字符与buf首字符比较,两种情况,如下
①如果从str首字符一直比到str尾字符都一样,则计数器+1,然后将str首字符移至buf第二个字符
②如果从str首字符开始比,中途有一个不匹配,则str首字符向buf的下一个字符移动,
重复上述两个动作,直到str首位移至buf的L2-L1-1位为止;

kmp思路:先求出第一个字符串的匹配表(若不会求看这篇 http://blog.csdn.net/nailnehc/article/details/47402529),然后就可以进行比较了,然后就没有然后来,直接记录出现次数,然后输出,(模板题真难写思路啊, href="/article/5224042.html" target=_blank>/article/5224042.html可以去看看这)

已Accept代码(用c提交)

Exe.TimeExe.MemoryCode Len.Language
78MS2708K643 BC
#include<stdio.h>
#include<string.h>
int p[10001];
int len1,len2,total;
char str[10001],buf[1000001];
void getp(){
int i=0,j=-1;
p[0]=-1;
while(i!=len1){
if(j==-1||str[i]==str[j]){
p[++i]=++j;
p[i]=str[i]!=str[j]?j:p[j];		//优化,可以看给你们提供的第二个博客的第五部分
}

else
j=p[j];
}
}

void kmp(){
int i=0,j=0;
while(i!=len2){
if(j==-1||buf[i]==str[j])
++i,++j;
else
j=p[j];
if(j==len1){
total++;
j=p[j];
}
}
}

int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%s%s",str,buf);
len1=strlen(str);
len2=strlen(buf);
total=0;
getp();
kmp();
printf("%d\n",total);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: