Hash——快速判斷兩個字符串是否相等


\(\text{Hash}\)原理

散列表(\(\text{Hash Table}\),也叫哈希表),是根據關鍵碼值(\(Key~value\))直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。

若關鍵碼值為 \(k\),則其值存放在 \(f(k)\) 的存儲位置上。由此,不需比較便可直接取得所查記錄。其中這個對應關系 \(f()\) 叫做 散列函數

對不同的關鍵字可能得到統一散列地址,即 \(k_1 \ne k_2\),而 \(f(k_1) = f(k_2)\),這種現象稱為碰撞(沖突)。


字符串\(Hash\)

算法梗概

用以快速判斷兩個字符串是否相等。

\(hash[1 \dots i]\)表示字符串中首字符到第 \(i\)個字符的哈希值。

\[hash[1 \dots i] = (hash[1 \dots i-1] \times k +str[i])~\%~p \]

其中:

  • \(k\) 可以取字符串元素種類,但更常取 \(31,~131\)等特殊數字。
  • \(p\) 取較大的質數,保證取模后的解集合的規模盡量的大。
    也可以直接用 unsigned 型來存儲,看作對 \(2^{32}\)\(2^{64}\) 取模,采用這種自然溢出方法的 \(\text{Hash}\),已經證明可以被特殊構造的字符串卡掉

如果不放心的話可以多取幾個大的質數分別取模判斷,二次或多次 \(\text{Hash}\)

性質

\(k\) 進制,對 \(p\) 取模,則有:

\[hash[1 \dots i] = (hash[1 \dots i-1] \times k +str[i]) ~ \% ~ p \]

即:

\[hash[1 \dots i] = (str[1]\times k^{i-1} + str[2] \times k^{i-2} + \dots + str[i-1] \times k + str[i])~\%~p \]

由此也可推出字符串從第\(i\)項到第\(j\)項的\(hash\)值為:

\[hash[i \dots j] = (str[i] \times k^{j-i} + str[i+1] \times k^{j-i-1} + \dots + str[j-1] \times k + str[j])~\%~p \]

那么如果我們已知\(hash[i \dots t] (i<t<j)\)\(hash[t+1 \dots j]\),該如何求出\(hash[i \dots j]\)呢?(即字符串的合並)

\[hash[i \dots j] = ((hash[i \dots t] \times k^{j-t})~\%~p + hash[t+1 \dots j])~\%~p \]

處理完合並,在已知\(hash[1 \dots j]\)\(hash[1 \dots i-1]~(2<i<j)\)的情況下,又應該怎樣求出\(hash[i \dots j]\)呢?(即字符串的拆分)

\[hash[i \dots j] = (hash[1 \dots j] - (hash[1 \dots i-1] \times k^{j-i+1}) ~\%~ p) ~\%~ p \]

已知兩端字符長度與 \(hash\) 值,可以進行快速的合並。

已知前綴 \(hash\) 值,可以快速求出區間 \(hash\) 值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM