【总结】字符串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;
}