對於一個字符串能夠將其化爲以一個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這個位置的字符組成的子串轉化爲數字返回的哈希值)ios
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^nspa
#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 */
相關文章連接:.net
https://pks-loving.blog.luogu.org/zi-fu-chuan-xue-xi-bi-ji-ha-xi-hash-yu-zi-dian-shu-trie3d
http://www.javashuo.com/article/p-grdrmdrj-mu.htmlcode