雜湊 字串雜湊演算法

2021-10-19 11:43:53 字數 1622 閱讀 1451

給定乙個長度為n的字串,再給定m個詢問,每個詢問包含四個整數l1,r1,l2,r2,請你判斷[l1,r1]和[l2,r2]這兩個區間所包含的字串子串是否完全相同。

字串中只包含大小寫英文本母和數字。

輸入格式

第一行包含整數n和m,表示字串長度和詢問次數。

第二行包含乙個長度為n的字串,字串中只包含大小寫英文本母和數字。

接下來m行,每行包含四個整數l1,r1,l2,r2,表示一次詢問所涉及的兩個區間。

注意,字串的位置從1開始編號。

輸出格式

對於每個詢問輸出乙個結果,如果兩個字串子串完全相同則輸出「yes」,否則輸出「no」。

每個結果佔一行。

/*根據定義分別求出hash[i]

hash[1]=s1hash[1]=s1

hash[2]=s1∗p+s2hash[2]=s1∗p+s2

hash[3]=s1∗p2+s2∗p+s3hash[3]=s1∗p2+s2∗p+s3

hash[4]=s1∗p3+s2∗p2+s3∗p+s4hash[4]=s1∗p3+s2∗p2+s3∗p+s4

hash[5]=s1∗p4+s2∗p3+s3∗p2+s4∗p+s5hash[5]=s1∗p4+s2∗p3+s3∗p2+s4∗p+s5

現在我們想求s3s4的hash值,不難得出為s3∗p+s4,並且從上面觀察,如果看hash[4]−hash[2]並將結果種帶有s1,s2係數的項全部消掉,

就是所求。但是由於p的階數,不能直接消掉,所以問題就轉化成,將hash[2]乘乙個關於p的係數,在做差的時候將多餘項消除,從而得到結果。

不難發現,對應項係數只差乙個p2,而4 - 3 + 1 = 2(待求hash子串下標相減再加一),這樣就不難推導出來此例題的求解式子。

hash[4]−hash[2]∗p4−2+1

至此,通過對上例的歸納,可以得出如下的公式。

公式若已知乙個|s|=n|s|=n的字串的hash值,hash[i],1≤i≤n,其子串sl..sr,1≤l≤r≤n對應的hash值為:

hash=hash[r]−hash[l−1]∗p[r−l+1]

*/const

int n =

100010

, p =

131;

// 這裡的p 是經驗值 131 ,或者13331

int n,m;

char str[n]

;// 這裡用unsigned long long 儲存就相當於mod 2 ^ 64, 因為超過了會溢位的

ull h[n]

, p[n]

;// h是儲存字串雜湊值的 p 是儲存p次方的

ull get

(int l,

int r)

intmain()

while

(m --

)return0;

}

字串演算法 字串雜湊

方法以,m進製的形式來表示乙個字串,那麼這個字串就可以輕鬆計算 i j 之間的hash值 當只有小寫 大家字母時,m 131 而hash值,可以使用unsigned long long 來表示,這時不再需要求餘 方法應用 字串匹配。思路 對比hash值 允許k次失配的字串匹配 即 允許k次字元值不對...

字串匹配 雜湊演算法

尋找字串s中字串t出現的位置或次數的問題屬於字串匹配問題。我們接下來討論中假設s的字串長度為 n,t的長度為m。最樸素的想法是,列舉所有起始位置,再直接檢查 是否匹配,複雜度為o nm 的演算法。還有幾個為高效的演算法。而在此我們只介紹實現起來較為容易,而在一些稍作變化的問題中同樣適用,並且可以簡單...

字串雜湊

參照演算法筆記p109,甲級1039 先假設字串均由大寫字母a z構成。在這個基礎上,不妨把a z視為0 25,這樣就把26個大寫字母對應到了26進製中。接著,按照將26進製轉化為10進製的思路,由進製的轉換結論可知,在進製轉換過程中,得到的10進製肯定是唯一的,由此便可實現將字串對映為整數的需求 ...