從動態規劃到配對序列聯配(二)

2021-10-03 21:02:21 字數 2013 閱讀 7548

閱讀本文前,建議先去閱讀從動態規劃到配對序列聯配(一)

上乙個例子的斐波那契數列過於簡單,以至於難以體現出使用dp程式設計的具體步驟。這次我們以乙個具體的例子來講解dp演算法解決問題三個步驟,即

定義子問題:通過數學符號描述子問題的狀態

定義狀態陣列:記錄計算過程中得到中間結果,方便後續呼叫

定義動態轉移方程:如何從前乙個問題推導出當前問題

大部分搜尋引擎都有乙個功能,能夠對你的輸入嘗試進行糾錯,例如我故意把ggplot2輸入成ggpolt2,搜尋很智慧型的將這個錯誤輸入替換成了「它認為正確」的輸入。

自動替換

評估兩個字串的相似度有兩個常用方法,最長公共子串(longest common substring length)和萊溫斯坦距離(levenshtein distance). 最長公共子串允許插入和刪除,描述的是兩個字串相同的子串長度,也就是相似程度。萊溫斯坦距離允許插入,刪除和替換,描述乙個字串轉變另乙個字串所需要的操作次數,也就是相異程度。

距離評估

後續只演示如何使用dp計算兩個字串的萊溫斯坦距離。

我們需要先定義子問題,也就是把複雜的問題拆解成容易解決的簡單問題,並能用數學符號進行描述其狀態。這裡就有乙個問題,我們需要使用幾個數學符號?我們可以通過分析問題中自變數因變數來確定數學符號的數量。在本問題中,自變數就是兩個字串的長度,而因變數就是隨著長度(自變數)改變而發生改變的編輯次數。於是我們用f(i,j)表示字串1(後面簡稱s1) 前i 個字元和字串2(後面簡稱s2) 前j個字元的編輯次數。

我們可以發現,在定義子問題的狀態過程時,涉及到兩個變數,因此我們用乙個二維陣列表示不同組合的狀態,定義為dp[i][j]

接著我們來思考當前狀態和之前的狀態的關聯。根據可能的操作(插入,刪除和替換),當前的子問題可以由三種情況中的一種轉移過來(後續舉例基於當前狀態s1="gg", s2="gg" )

當前選擇策略,取決於每個子問題狀態的取值,我們從中選取最小的編輯次數作為當前的操作。

我們可以手工的方式根據狀態轉移方程填充我們的狀態陣列,如下所示。

狀態轉移表

知道思路之後,就可以寫**了。以c++為例

#include #include #include #include using namespace std;

int dist(string s1, string s2)

for (int i = 0; i < n+1; i++)

//遞迴狀態表

for (int i = 1; i < m + 1; i++) else;

dp[i][j] = *min_element(state.begin(), state.end()) + 1;

}//printf("%d-%d: %d\n",i, j, dp[i][j]);}}

//輸出結果

return dp[m][n];

}int main(int argc, char const *ar**)

**都是基本語法,很容易轉成其他程式語言(r語言要注意陣列從1開始,而不是0)。個人覺得有以下幾個注意點

但你學習了編輯距離後,是不是感覺這和我們的序列聯配有點相似,都是通過一系列操作的將乙個序列轉成另乙個序列。我可以列舉下兩者的聯絡

為了評估兩個序列的相似度,我們可以評估兩個序列聯配後的得分大小,不同的操作有不同的分,也就是得分矩陣(score matrix)。

另外為了輸出最終的聯配後續列,我們需要從最優狀態不斷溯源(trace back),從而得到聯配結果。

動態規劃(二)最長回文子串行

所說的子串行不一定是連續的,但是順序不變。子串必須是連續的字元組成。最優子結構 假設s i j 是給定的字串,長度為n,讓dp i j 表示從s i 到s j 包含的最長回文子串行的長度。初始化 dp i i 1 如果s i s j dp i j dp i 1 j 1 2 如果s i s j dp ...

動態規劃 不同的子串行(二)

給定乙個字串s,計算s的不同非空子序列的個數。因為結果可能很大,所以返回答案模10 9 7.示例 1 輸入 abc 輸出 7 解釋 7 個不同的子串行分別是 a b c ab ac bc 以及 abc 示例 2 輸入 aba 輸出 6 解釋 6 個不同的子串行分別是 a b ab ba aa 以及 ...

動態規劃系列二(最長有序子串行)

1 問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 ...