POJ3461-字符串匹配(基础)

这道题很水..很基础..
纯kmp就能过..
但这是我第一次用kmp,感觉好厉害,所以写这个博客来加深对kmp的印象。
附上我看的kmp算法讲解 (这么好的博客居然只有25粉丝)
http://www.cnblogs.com/c-cloud/p/3224788.html
然后是我的蒟蒻幼稚代码 代码风格幼稚到底算是优点还是缺点呢?

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,cnt,lenw,lent,next[10005];
char w[10005],t[1000005];
void make_next(){
    next[0]=0;
    for(int i=1,k=0;i<lenw;++i){
        while(k>0&&w[k]!=w[i]){
            k=next[k-1];
        }
        if(w[k]==w[i])k++;

        next[i]=k;

    }
    return ;
}
int kmp(){
    int cnt=0;
    for (int i=0,j=0;i<lent;++i){

        while(j>0&&w[j]!=t[i])
            j=next[j-1];
        if (w[j]==t[i])
        {
            j++;
        }
        if (j==lenw)
        {
            cnt++;
            j=next[j-1];//这条是我看了学长的代码之后加的  算是个小优化
        }

    }    
    return cnt;
}
int main(){
    scanf("%d",&n);
    while(n--){
        scanf("%s %s",w,t);
        lenw=strlen(w);
        lent=strlen(t);

        make_next();

        printf("%d\n",kmp());

    }


}

再附上我TLE的sunday算法 多可爱的算法 可惜被卡掉了

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,lenw,lent,pos[200],cnt,sw;
char w[10006],t[1000005];
bool check(int i){
    for(int k=0;k<lenw;++k){
        if(w[k]!=t[i+k])return 0;
    }
    return 1;
}
int main(){
    scanf("%d",&n);
    while(n--){
        scanf("%s",w);
        scanf("%s",t);
        cnt=0;
        memset(pos,0,sizeof pos);
        sw=0;
        lenw=strlen(w);
        lent=strlen(t);
        for(int i=0;i<lenw;++i){
            pos[w[i]]=i;
        }

        while(sw+lenw<=lent){
            if(check(sw)){cnt++;sw++;}
            else {
                sw+=lenw-pos[t[sw+lenw]];
            }
        }
        printf("%d\n",cnt);
    }


}

至于字符串hash算法,我还没学会。之后会补上的。


填坑。查到了我能看懂的字符串hash。
转载自sxy_cnyalihttp://blog.csdn.net/sxy_cnyali/article/details/50619603

戳这里是他的新blog

#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
#include<iostream>  
#include<algorithm>  
#define ull unsigned long long  
using namespace std;
const ull B=1e8+7,C=1e8+119;  
const int dmax=1000100;  
char s[dmax],s1[dmax];  

int hash(char *a,char *b){  
    int ans=0,i;  
    ull x=strlen(a),y=strlen(b),t=1,t1=1;  
    ull ah=0,bh=0,al=0,bl=0;  
    if (x>y)  
        return 0;  
    for (i=0;i<x;i++){  
        t*=B,t1*=C;  
        ah=ah*B+a[i],bh=bh*B+b[i];  
        al=al*C+a[i],bl=bl*C+b[i];  
    }  
    for (i=0;i+x<=y;i++){  
        if (al==bl && ah==bh)  
            ans++;  
        if (i+x<y){  
            bh=bh*B-b[i]*t+b[i+x];  
            bl=bl*C-b[i]*t1+b[i+x];  
        }  
    }  
    return ans;  
}  

int main(){  
    int T;  
    scanf("%d",&T);  
    getchar();  
    while (T--){  
        gets(s1);  
        gets(s);  
        printf("%d\n",hash(s1,s));  
    }  
    return 0;  
}  

(侵删致歉)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值