乙個自己研究出來的字串匹配演算法 k子串演算法

2021-09-08 19:21:36 字數 1266 閱讀 8462

舉個反例:

a=kabcdelmabcdefgnfghijk

b=kabcdefghijk

k=2按照這種方式選取結果為:abcdefg+hijk,總長度為7+4=11,但是最優解為:kabcde+fghijk總長度為6+6=12。

舉個反例:

a=efgijabc

b=abcefhij

k=1按照這種方式選取,首先求出最長公共子串行ef-ij,取出其中最長一段長度為2。而最優解為:abc,長度為3。

上面兩個看似取巧但是不對的想法被推翻後,也能讓我靜下心來進行系統性的思考了,正確解法為動態規劃。動態規劃最重要的事情有三件:找問題的狀態,找轉移方程邊界初始化。找對狀態就相當於成功了一半,找到轉移方程基本問題就算解了,邊界初始化可以忽略不計。找狀態除了靠靈感之外,我最喜歡的方法是分解問題,找到問題的最原子的狀態,之後搭積木般的組合拼裝就ok了。

設dp[i][j][k]表示為以a[i],b[j]為第k個公共子串結尾時,所能得到的最大值。其中a[i]為字串a第i個字元,b[j]為字串b的第j個字元。

在考慮a[i]和b[j]時,如果a[i] = b[j],那麼a[i],b[j]可以單獨組成第k個串,也可以和a[i-1],b[j-1]組合在一起作為第k個串,則轉移方程如下:

dp[i][j][k] = dp[i-1][j-1][k] + 1             (與a[i-1],b[j-1]連在一起)

dp[i][j][k] = max(dp[i'][j'][k-1] + 1)      (a[i],b[j]單獨成為第k個串)

當單獨成串時,需要遍歷所有i',j',如果我們能在計算dp[i][j][k]的時候順便記錄截止到當前選取k個串時的最大值的話,就可以避免遍歷,所以最後的狀態以及轉移方程如下:

dp[i][j][k] = max(dp[i-1][j-1][k] + 1, maxscore[i-1][j-1][k-1] + 1)

maxscore[i][j][k] = max(maxscore[i-1][j][k],maxscore[i][j-1][k], dp[i][j][k])

現在回頭看一下這個演算法,當k=1的時候就是最長公共子串問題,當k=min(length(a), length(b))的時候就是最長公共子串行問題,想想還是挺有意思是的。

對於乙個棘手的問題,可能一開始想不到正確的演算法,我們這時可以盡可能的把能想到的解法全都考慮一遍,該推翻的推翻,該證明的證明,在推翻和證明的過程中更深刻的理解這個問題,最終找到正確的答案。

阮一峰 字串匹配的Boyer Moore演算法

但是,它並不是效率最高的演算法,實際採用並不多。各種文字編輯器的 查詢 功能 ctrl f 大多採用 boyer moore 演算法。boyer moore 演算法不僅效率高,而且構思巧妙,容易理解。1977 年,德克薩斯大學的 robert s.boyer 教授和 j strother moore...

阮一峰 字串匹配的Boyer Moore演算法

阮一峰 字串匹配的boyer moore演算法 但是,它並不是效率最高的演算法,實際採用並不多。各種文字編輯器的 查詢 功能 ctrl f 大多採用 boyer moore 演算法。boyer moore 演算法不僅效率高,而且構思巧妙,容易理解。1977 年,德克薩斯大學的 robert s.bo...

乙個單詞是否為其他字串的字串

題目 假定有乙個方法issubstring,可檢查乙個單詞是否為其他字串的字串。給定兩個字串s1和s2,請編寫 檢查s2是否為s1旋轉而成,要求只能呼叫一次issubstring。比如,waterbottle是erbottlewat旋轉後的字串。解答 另x wat,y erbottle 則s1 xy...