【总结】字符串Hash处理KMP

前言

因为今天考试不会Hash然后只会yy结论,于是决定苦练Hash。。。

题面

原题

Solution

考虑可以把每一个东西都搞出来,然后处理一下Hash关系就好了。。。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
#define ull unsigned long long
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
using namespace std;
inline int gi(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
inline ll gl(){
    ll sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int N=1000010;
ull Hash[N],Hash2[N],Pow[N];
int nxt[N],n,m;
char s[N],t[N];
const int base=19260817;
ull check(int l,int r){
    return Hash[r]-Hash[l-1]*Pow[r-l+1];
}
void Get_Fail(){
    nxt[1]=0;
    for(int i=1;i<=m;i++){
        int j=nxt[i];
        while(j && t[j]!=t[i])j=nxt[j];
        if(t[j]==t[i])j++;
        nxt[i+1]=j;
    }
}
int main(){
    int i,j,k;
    cin>>s>>t;
    n=strlen(s);m=strlen(t);
    Hash[0]=s[0];
    for(i=1;i<n;i++)
        Hash[i]=Hash[i-1]*base+s[i];
    Hash2[0]=t[0];
    for(i=1;i<m;i++)
        Hash2[i]=Hash2[i-1]*base+t[i];
    Pow[0]=1;
    for(i=1;i<=n;i++)Pow[i]=Pow[i-1]*base;
    for(i=m;i<=n;i++)
        if(check(i-m,i-1)==Hash2[m-1])
            printf("%d\n",i-m+1);
    Get_Fail();
    for(i=1;i<=m;i++)printf("%d ",nxt[i]);
    puts("");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cjgjh/p/9839680.html