hash,hash表应用

hash算法,在我的理解中就是,将一个字符串转化为一个可以代表它的数字,在调用,查询这个字符串时,就大大缩短了时间复杂度。

hash表算法,对于一个字符串,进行如下操作 hash[i]=hash[i-1]*base+s[i]的操作,将字符串的每一部分转化为数字的值都存入数组,如此一来,想要查询这个字符串中的任何一部分都是可以的。这样取字符串中任何一段,都可以用o(1)的算法实现。

对于hash表中,某一子串的查找:hash[x]-hash[y]*xp[y-x+1];

例题:

poj 3461

对于这个题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;
}

HYSBZ - 3916

代码:

#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;
}

猜你喜欢

转载自blog.csdn.net/Black__wing/article/details/82628466