hash算法,在我的理解中就是,将一个字符串转化为一个可以代表它的数字,在调用,查询这个字符串时,就大大缩短了时间复杂度。
hash表算法,对于一个字符串,进行如下操作 hash[i]=hash[i-1]*base+s[i]的操作,将字符串的每一部分转化为数字的值都存入数组,如此一来,想要查询这个字符串中的任何一部分都是可以的。这样取字符串中任何一段,都可以用o(1)的算法实现。
对于hash表中,某一子串的查找:hash[x]-hash[y]*xp[y-x+1];
例题:
对于这个题hash做法,先求出模板串的hash值,预处理出查找串的hash表,然后用模板串的hash值,在查找串上对比,找子串与模板串是否相同。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<string.h>
using namespace std;
const int base=31;
const int maxn=1e6+5;
long long hash[maxn],xp[maxn];
char s1[maxn],s2[maxn];
int main()
{
xp[0]=1;
for(int i=1;i<=maxn;i++)
xp[i]=xp[i-1]*base;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s1);
scanf("%s",s2);
long long ss1=0;
for(int i=strlen(s1)-1;i>=0;i--)
{
ss1=ss1*base+s1[i];
}
hash[strlen(s2)]=0;
for(int i=strlen(s2)-1;i>=0;i--)
{
hash[i]=hash[i+1]*base+s2[i];
}
long long ans=0;
for(int i=0;i<=strlen(s2)-strlen(s1);i++)
{
if(hash[i]-hash[i+strlen(s1)]*xp[strlen(s1)]==ss1)
ans++;
}
printf("%lld\n",ans);
}
return 0;
}
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <string.h>
const int M=2e6+10;
using namespace std;
long long base = 31,n;
long long xp[M],hash[M];
char a[M];
long long work(long long x,long long y)
{
if(x>y)
return 0;
return hash[y]-hash[x-1]*xp[y-x+1];
}
long long judge(long long x)
{
long long w1=0,w2=0;
if(x<=n/2)
w1=work(1,x-1)*xp[n/2+1-x]+work(x+1,n/2+1);
else
w1=work(1,n/2);
if(x>n/2+1)
w2=work(n/2+1,x-1)*xp[n/2+n/2+1-x]+work(x+1,n);
else
w2=work(n/2+2,n);
if(w1==w2) return w1;
else
return 0;
}
int main()
{ xp[0]=1;
for(int i=1;i<M;i++)
xp[i]=xp[i-1]*base;
while(~scanf("%lld",&n))
{
scanf("%s",a+1);
if(n%2==0)
{
printf("NOT POSSIBLE\n");
break;
}
hash[0]=0;
for(long long i=1;i<=n;i++)
{
hash[i]=hash[i-1]*base+a[i];
}
long long ans=0,w,h=0;
for(long long i=1;i<=n;i++)
{
w=judge(i);
if(w)
{
if(ans==0)
ans=i,h=w;
else if(w!=h)
{
ans=-1;
break;
}
}
}
if(ans==0) printf("NOT POSSIBLE\n");
else if(ans==-1)printf("NOT UNIQUE\n");
else
{
for(long long i=1,l=0;l<n/2;i++)
if(i!=ans)printf("%c",a[i]),l++;
printf("\n");
}
}
return 0;
}