字符串哈希 哈希表

 

1.字符串哈希node

 

方法概述:ios

  • 選取兩個合適的互質常數b,h(b<h),把字符串當作b進制數,算出這個數模h
  • 設H(C,k)爲前k個字符構成的字符串的哈希值,則:H(C',k)=H(C,k+n)-H(C,k)*bn

                                                                                      --------具體見《信息學奧賽一本通提升篇》ide

 

關於正確性:能夠用雙哈希下降出現相同哈希值的機率 取109+7和109+9,就幾乎不可能發生衝突,由於它們是孿生質數函數

 

板子題:   poj3461spa

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define R register
 5 #define go(i,a,b) for(R int i=a;i<=b;i++)
 6 #define il inline
 7 #define ll unsigned long long//記得是unsigned long long
 8 #define M 1000001
 9 using namespace std;
10 il int rd()
11 {
12     int x=0,y=1;char c=getchar();
13     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
14     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
15     return x*y;
16 }
17 int T,l1,l2,ans,b=29;
18 char s1[M],s2[M],tmp[M];
19 ll dat,hash[M],p[M];
20 int main()
21 {
22     T=rd();
23     p[0]=1;go(i,1,1000000) p[i]=p[i-1]*b;
24     while(T--)
25     {
26         scanf("%s%s",s1+1,s2+1);ans=0;
27         l1=strlen(s1+1);l2=strlen(s2+1);
28         hash[0]=1;
29         go(i,1,l2) hash[i]=hash[i-1]*b+(ll)(s2[i]-'A'+1);
30         dat=0;
31         go(i,1,l1) dat=dat*b+(ll)(s1[i]-'A'+1);
32         go(i,0,l2-l1)
33         if(dat==hash[i+l1]-hash[i]*p[l1])ans++;
34         printf("%d\n",ans);
35     }
36     return 0;
37 }
View Code

 


 

 

2.哈希表.net

 

  哈希函數的構造:3d

  • 除餘法
  • 乘積取整法:用key乘以一個在(0,1)中的實數,獲得一個實數,取其小數部分乘以哈希表的大小再向下取整。(最好是無理數,(√5-1/2是一個實際效果很好的數) //我想我大概永遠不會用這種方法吧qwq
  • 基數轉換法:把key值當作另外一種進制的數,而後轉換成十進制,再用除餘法取餘

 

板子題: loj10034 圖書管理code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #define R register
 6 #define ll unsigned long long
 7 #define go(i,a,b) for(R int i=a;i<=b;i++)
 8 #define M 1000010
 9 using namespace std;
10 int rd()
11 {
12     int x=0,y=1;char c=getchar();
13     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
14     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
15     return x*y;
16 }
17 ll h1=29,h2=73,mod1=1e6+3,mod2=1e6+9,sm1,sm2,b[M];
18 int n,len,ct,l;
19 char tp[10],s[201];
20 struct node{ll w,nt;}a[M];
21 void insert() {a[++ct].nt=b[sm1];a[ct].w=sm2;b[sm1]=ct;}
22 bool find()
23 {
24     for(R int i=b[sm1];i;i=a[i].nt)
25         if(a[i].w==sm2) return 1;
26     return 0;
27 }
28 int main()
29 {
30     n=rd();
31     while(n--)
32     {
33         cin>>tp;gets(s);len=strlen(s)-1;
34         //用cin來讀入tp(type)讀到空格時就會中止 gets讀完一整行(包括換行)
35         sm1=0;sm2=0;
36         cout<<tp<<endl;
37         go(i,0,len) sm1=(sm1*h1+s[i])%mod1,sm2=(sm2*h2+s[i])%mod2;//雙哈希
38         if(tp[0]=='a') insert();
39         else if(find()) printf("yes\n");
40         else printf("no\n");
41     }
42     return 0;
43 }
View Code
相關文章
相關標籤/搜索