哈希与哈希表

 

一、字符串Hash

  实质:将字符串转化为数字形式

 

  适用范围:字符串匹配

 

  具体流程:

     哈希函数    

      对于一个字符串可以将其化为以一个b(b>1)进制的数字,则一个字符串转化为哈希值为:选取两个合适的互素常数b,h(l<b<h),假设字符串C=c1c2c3...cm,定义哈希函数:H(C,k)=(c1*b^(m-1)+c2*b^(m-2)+...+cm*b^0)mod h(H(C,K)代表的是字符串从1-K这个位置的字符组成的子串转化为数字返回的哈希值)

     滚动哈希

      H(C,k+1)=H(C,k)*b+c(k+1)

      对于一个字符串C=c1c2c4c4c5~cm,C的一个子串C’=C(k+1)C(k+1)C(k+2)~C(k+n),H(C')=H(C,k+n)-H(C,k)*b^n

   代码:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define FORa(i,s,e) for(LL i=s;i<=e;i++)
#define FORs(i,s,e) for(LL i=s;i>=e;i--)
using namespace std;


typedef long long LL; 
const int N=1000000;
LL m,n,T,b=27,ans;
string s1,s2;
LL pow[N+1],h[N+1];
int main()
{
    scanf("%d",&T);
    pow[0]=1;
    FORa(i,1,N) pow[i]=pow[i-1]*b;//预处理出b^k(0<=k<N) 
    while(T--)
    {
        cin>>s1>>s2;    
        n=s1.size(),m=s2.size(),ans=0;        
        FORa(i,1,m) h[i]=h[i-1]*b+LL(s2[i-1]-'A');//将前1-i位字符组成的字符串转化为哈希值 
        LL num_s=0;
        FORa(i,1,n) num_s=num_s*b+LL(s1[i-1]-'A');//计算出模式串的哈希值 
        FORa(i,1,m-n+1)
            if(num_s==h[i+n-1]-h[i-1]*pow[n])//枚举子串,检查 
                ans++;    
        printf("%lld\n",ans);
    }
    return 0;
}
/*1
BA
BBABA
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
*/

 

 

二、哈希表

    哈希函数的构造

  •   除语法
  •   乘积取整法
  •   基数转换法

 

相关文章链接:

  https://pks-loving.blog.luogu.org/zi-fu-chuan-xue-xi-bi-ji-ha-xi-hash-yu-zi-dian-shu-trie

  https://blog.csdn.net/u011109881/article/details/80379505

 

 

 

 

 

 

 

posted @ 2019-07-23 15:56  SeanOcean  阅读(235)  评论(0编辑  收藏  举报