题目描述:
求一个子串在主串中出现的次数。
解题思路:
kmp。稍微变一丢丢,就是计算次数而不是只匹配一次,只需要计算next[]索引多往后计算一位:因为如果在最后一位匹配完后的情况,模式串跳转的位置等同于在最后一位的后面那位失效的时候需要跳转到哪里。
一直搞不清楚的kmp这次总算是记住一个大概的思路了。。。。orz。折磨死了。
提交的时候tle了。。后来看discuss里说的是不要在循环条件里写strlen()。果真是这问题。。。。下次注意下好了,,重复计算strlen比较耗时。
代码:
#include
#include
#define W 10001
#define T 1000001
char word[W], text[T];
int next[W], cnt;
main(){
int t, i, k;
int tlen, wlen;
scanf("%d",&t);
while(t>0){
cnt = 0;
scanf("%s %s",word, text);
//find next[] of word
next[0] = -1;
wlen = strlen(word);
for(i=1;i<=wlen;i++){ // for this problem add next[strlen()]
k = next[i-1];//find former skip
while(k!=-1 && word[k] != word[i-1]){
k = next[k];
}
next[i] = k+1;
}
//print next
// for(i=0;i<=strlen(word);i++){
// printf("%d ",next[i]);
// }
// printf("\n");
//find matching cnt
k = 0;
tlen = strlen(text);
for(i=0;i
if(word[k] != text[i]){ //not matching
while(k!=-1 && word[k] != text[i]){ //change index of word
k = next[k];
}
if(-1 == k){ //back to the first of word
k=0;
continue;
}
}
//matching
k++;
if( k == wlen){ //matching
cnt ++;
k = next[k];
}
}
printf("%d\n",cnt);
t--;
}
system("pause");
return 0;
}