改进的字符hash

来源:互联网 发布:网络情感骗局男的手法 编辑:程序博客网 时间:2024/05/17 05:52

在前几篇文章中我有把萌教主的字符hash贴出来,不过之后我有用base=10和‘a’到‘a’+10之间的字符来测试,发现他是倒过来的,很不好理解;所以我又按照正常顺序来写,测试过后发现好理解多了,目前看来对子串的匹配没有影响:下面给出改进后的版本(记得使用时要把base值改过来):

#include<cstring>#include<string>#include<iostream>#include<cstdio>using namespace std;const int maxn=1e7+7;typedef long long ll;ll Hash[maxn],xp[maxn],Hash1[maxn];int base=10;int main(){    //freopen("int.txt","r",stdin);    xp[0]=1;    for(int i=1;i<maxn;i++)        xp[i]=xp[i-1]*base;    string a;    cout<<"请输入子串"<<endl;    cin>>a;    int L=a.length();    Hash[0]=0;    ll a_num=0;    for(int i=0;i<L;i++){        Hash[i+1]=Hash[i]*base+a[i]-'a'+1;        a_num=a_num*base+a[i]-'a'+1;    }    string b;    cout<<"请输入模式串"<<endl;    cin>>b;    int len=b.length();    Hash1[0]=0;    for(int i=0;i<len;i++)        Hash1[i+1]=Hash1[i]*base+b[i]-'a'+1;        bool flag=false;    cout<<"子串的数值:"<<a_num<<endl;    cout<<"模式串的每一个数值:"<<endl;    for(int i=1;i<=len;i++){        cout<<i<<':'<<Hash1[i]<<endl;    }    printf("xp[L]=%d\n",xp[L]);    for(int i=0;i+L<=len;i++){        printf("i %d->i+l %d: %lld\n",i,i+L,Hash1[i+L]-Hash1[i]*xp[L]);        if(a_num==(Hash1[i+L]-Hash1[i]*xp[L])){            flag=true;            printf("Yes\n");        }    }    if(!flag)printf("No\n");    return 0;}


0 0