poj3461_kmp

题目描述:

   求一个子串在主串中出现的次数。

 

解题思路:

  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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值