字串演算法1 再談字串Hash(優雅的暴力)

2022-05-30 17:48:11 字數 2944 閱讀 5477

- 什麼是字串hash?

- 就是把字串對映成乙個數字使每個字串的對映結果不一樣(把字串有效的轉化為數字

對乙個字元進行唯一編碼,如a-->1,b-->2,c-->3等等

一般不用ascii碼表來對映而是轉化為相對小一點的值來對映

提示資訊: (字串內包含數字、大小寫字母,大小寫敏感)

寫出val函式對映字元:

int val(char

ch)

一般對映方法: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,int

p)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: 複製

5

abcaaaa

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...