- 什麼是字串hash?
- 就是把字串對映成乙個數字使每個字串的對映結果不一樣(把字串有效的轉化為數字)
對乙個字元進行唯一編碼,如a-->1,b-->2,c-->3等等
一般不用ascii碼表來對映而是轉化為相對小一點的值來對映
提示資訊: (字串內包含數字、大小寫字母,大小寫敏感)
寫出val函式對映字元:
int val(charch)
一般對映方法:hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保險度:****)
hash[i]表示字串的第i個字首的hash值
hash值的性質
①這樣子,我們就可以記錄下每個字串對應的整數,當下一次出現了乙個已經出現的字串時,查詢整數是否出現過,就可以知道 字串是否重複出現。
②判斷兩個字串是否一致,怎麼辦呢?直接用它們的hash值判斷即可,若hash值一致,則認為字串一致;
若hash值不一致,則認為是不同的字串。
例子
假設我們取p=13 ,mod=101
先把abc對映為乙個整數
hash[0]=1,表示 a 對映為1
hash[1]=(hash[0]*p+idx(b))%mod=15,表示 ab 對映為 15
hash[2]=(hash[1]*p+idx(c))%mod=97
這樣,我們就把 abc 對映為 97 這個數字了。
衝突:假設mo數和基底e取值不當時就會發生衝突
就是兩個字串明明不同但對映出來的結果相同
舉個極端的例子
e=0的情況 字串"a"和字串"b"對映出來的值都是0,就產生衝突
那麼怎麼調整才能使衝突概率小之又小呢?
- p取乙個較大素數,mo取乙個大素數。
習慣上,p取乙個6到8位的素數即可,mo一般取大素數 1e9+7(1000000007)或
1e9+9(1000000009)【逃 19260817】
求出每個子串的hash值
注意到每乙個hash[i]都是字首和數字那麼我們借用字首和的思想,已知hash[r]和hash[l]求出hash(l,r)表示前[l,r]子串的hash值
hash[l]=(x1*el-1+x2*el-2+......+xl*e0)mod mo
hash[l-1]=(x1*el-2+x2*el-3+......+xl-1*e0)mod mo
hash[r]=(x1*er-1+x2*er-2+......+xr
*e0)mod mo
hash(l,r)=(xl*er-l+xl+1*er-l-1+......xr-1*e1+xr*e0)mod mo
hash[l-1]*er-l+1=(x1*el-2+x2*el-3+......+xl-1*e0)*er-l+1mod mo=(x1*er-1+x2*er-2+......+xl-1*er-l+1)mod mo
hash[r]-hash[l-1]*er-l+1=((x1*er-1+x2*er-2+...xl-1*er-l+1+xl*er-l...+xr*e0)-(x1*er-1+x2*er-2+......+xl*er-l+1))mod mo =(xl*er-l+xl+1*er-l-1+......xr-1*e1+xr*e0)mod mo=hash(l,r)
所以:hash[r]-hash[l-1]*er-l+1=hash(l,r)
ll pow(int x,int n,intp)ll hash(
int l,int
r)
其他hash方法
1. unsigned long long hash[n];
hash[i]=hash[i-1]*p(自動取模) (保險度***) 常數(幾乎沒有) (容易被卡)
2. hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保險度****) 常數(有一點) (一般)
3. 雙hash
hash1[i]=(hash1[i-1]*p+idx(s[i]))%mod1
hash2[i]=(hash2[i-1]*p+idx(s[i]))%mod2
pair表示乙個字串! (保險度*****) 常數(比較大)(孿生質數不可能被卡)
推薦 :hash[i]=(hash[i-1]*p+idx(s[i]))%mod (保險度****) 常數(有一點) (一般)
如題,給定n個字串(第i個字串長度為mi,字串內包含數字、大小寫字母,大小寫敏感),請求出n個字串中共有多少個不同的字串。
輸入格式:
第一行包含乙個整數n,為字串的個數。
接下來n行每行包含乙個字串,為所提供的字串。
輸出格式:
輸出包含一行,包含乙個整數,為不同的字串個數。
輸入樣例#1: 複製
5abcaaaa
abcabcc
12345
輸出樣例#1: 複製
4
時空限制:1000ms,128m
資料規模:
對於30%的資料:n<=10,mi≈6,mmax<=15;
對於70%的資料:n<=1000,mi≈100,mmax<=150
對於100%的資料:n<=10000,mi≈1000,mmax<=1500
樣例說明:
樣例中第乙個字串(abc)和第三個字串(abc)是一樣的,所以所提供字串的集合為,故共計4個不同的字串。
tip: 感興趣的話,你們可以先看一看以下三題:
bzoj3097:
bzoj3098:
bzoj3099:
如果你仔細研究過了(或者至少仔細看過ac人數的話),我想你一定會明白字串雜湊的正確姿勢的^_^
字串 字串雜湊hash演算法
以洛谷p3370為引子引入吧 雜湊其實是所有字串操作中,筆者認為最簡單的操作了 except輸入輸出qwq 雜湊的過程,其實可以看作對乙個串的單向加密過程,並且需要保證所加的密不能高概率重複 就像不能讓隔壁老王輕易地用它家的鑰匙開啟你家門一樣qwq 通過這種方式來替代一些很費時間的操作。比如,最常見...
演算法 字串hash
題目描述 很久很久以前,森林裡住著一群兔子。有一天,兔子們想要研究自己的 dna 序列。我們首先選取乙個好長好長的 dna 序列 小兔子是外星生物,dna 序列可能包含 26 個小寫英文本母 然後我們每次選擇兩個區間,詢問如果用兩個區間裡的 dna 序列分別生產出來兩隻兔子,這兩個兔子是否一模一樣。...
演算法 字串Hash
字串hash主要應用在 在長度為n的主串s中匹配長度為m的匹配串t,返回起始位置。通過字串hash函式把乙個任意長度的字串對映成乙個非負整數,並且其衝突概率為零。取一固定值p,把字串看作p進製數,並分配乙個大於0的數值,代表每種字元。一般來說,我們分配的數值都遠小於p。取一固定值m,求出p進製數對m...