生成乙個長度為l陣列的雜湊碼,需要o(l)時間。
如何在常數時間生成滑動視窗陣列的雜湊碼?利用滑動視窗的特性,每次滑動都有乙個元素進,乙個出。
由於只會出現小寫的英文本母,因此可以將字串轉化成值為 0 到 25 的整數陣列: arr[i] = (int)s.charat(i) - (int)『a』。
按照這種規則,abcd整數陣列形式就是 [0, 1, 2, 3],轉換公式如下所示。
可以將上面的公式寫成通式,如下所示。其中 ci為整數陣列中的元素,a = 26,其為字符集的個數。類似於26進製數轉換成10進製數一樣。
下面來考慮視窗從abcd滑動到bcde的情況。這時候整數形式陣列從 [0, 1, 2, 3] 變成了 [1, 2, 3, 4],
陣列最左邊的 0 被移除,同時最右邊新添了 4。滑動後陣列的雜湊值可以根據滑動前陣列的雜湊值來計算,
計算公式如下所示。
寫成通式如下所示。
如何避免溢位:al可能是乙個很大的數字,因此需要設定數值上限來避免溢位。
設定數值上限可以用取模的方式,即用 h % modulus 來代替原本的雜湊值。
hash碰撞問題:
最後如果得到的hash之相同,還要檢查子串和目標串是否相同
複雜度分析時間複雜度:
o(n),計算 needle 字串的雜湊值需要 o(l) 時間,之後需要執行 (n−l) 次迴圈,每次迴圈的計算複雜度為常數。
空間複雜度:o(1)。
rabin-karp演算法被稱道的三個原因
它可以用來檢測抄襲,因為它能夠處理多模式匹配;
rabin-karp演算法能夠有效地檢測抄襲
雖然在理論上並不比暴力匹配法更優,但在實際應用中它的複雜度僅為o(n+m);
如果能夠選擇乙個好的雜湊函式,它的效率將會很高,而且也易於實現。
rabin-karp演算法被詬病的兩個原因
有許多字串匹配演算法的複雜度小於o(n+m);
有時候它和暴力匹配法一樣慢,並且它需要額外空間。
結語:
rabin-karp演算法之所以出眾最大的原因就是它可以對多模型進行匹配。
這一特性使得它在檢測抄襲方面(尤其是大篇幅文字)非常好用。
1package
字串匹配;23
public
class
滾動hash
16if(h0 == l0 && needle.equals(haystack.substring(0, l)))
19int al = 1;
20for (int i = 1; i < l; i++)
23for (int i = l; i < n; i++) 28}
29return -1;30}
31public
static
void
main(string args)
34 }
字串匹配 Hash
俗話說 字串問題只有一種做法 hash hash hash 給定兩個由小寫字母構成的字串 l 和 s 請你從左到右,找出子串 l 在母串 s 中每次出現的開始位置 匹配位置 第一行 給乙個全由小寫字母構成的母串 s 0 s的長度 1000000 第二行 給乙個全由小寫字母構成的子串 l 0 l的長度...
Hash 字串 字串雜湊
luo gu luogu luogup 3370 p3370 p337 0如題,給定n個字串 第i個字串長度為mi,字串內包含數字 大小寫字母 請求出n個字串中共有多少個不同的字串。第一行包含乙個整數n,為字串的個數。接下來n行每行包含乙個字串,為所提供的字串。輸出包含一行,包含乙個整數,為不同的字...
典型字串匹配演算法實現 單字串匹配演算法
部落格源址 相信大家對快捷鍵ctrl f是做什麼用的都應該很熟悉了,無論是文字編輯 網頁瀏覽等程式上它都意味著字串搜尋,我們提供乙個關鍵字,它將找到當前頁面上的所有該關鍵字所在的位置。關鍵字稱為模式串,在文字t中尋找模式串p出現的所有出現的位置,解決這種問題的演算法叫做字串匹配演算法。字串匹配演算法...