給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行。
乙個字串的 子串行 是指這樣乙個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,「ace」 是 「abcde」 的子串行,但 「aec」 不是 「abcde」 的子串行。兩個字串的「公共子串行」是這兩個字串所共同擁有的子串行。
採用動態規劃的策略,與最大上公升子串行長度的動態規劃解法不同的是,採用了二維的dp 陣列(**) 而非一維dp陣列。
狀態定義:
為了表示方便,先舉例:
text1 = "abcd"
text2 = "ace"
dp table\「」
「a」「b」
「c」「d」「」0
0000
「a」011
11「c」011
22「e」011
22橫軸、縱軸分別表示兩個字串的各個字元, 其中從第一列(行)表示空串的情況。
d p[
i][j
]dp[i][j]
dp[i][
j]表示text2的前i個字元子串和text1的前j個字元字串的lcs(longest common string)長度。邊界狀態:當其中乙個為空串時,其lcs值必為0。
狀態轉移方程:
d p[
i+1]
[j+1
]=dp
[i][
j]+1
ifte
xt1[
i+1]
==te
xt2[
j+1]
dp[i+1][j+1] =dp[i][j]+1 \ if \ text1[i+1]==text2[j+1]
dp[i+1
][j+
1]=d
p[i]
[j]+
1ift
ext1
[i+1
]==t
ext2
[j+1]dp
[i+1
][j+
1]=m
ax(d
p[i]
[j+1
],dp
[i+1
][j]
)ift
ext1
[i+1
]!=t
ext2
[j+1
]dp[i+1][j+1] =max(dp[i][j+1], dp[i+1][j]) if \ text1[i+1]\ != text2[j+1]
dp[i+1
][j+
1]=m
ax(d
p[i]
[j+1
],dp
[i+1
][j]
)ift
ext1
[i+1
]!=t
ext2
[j+1
]簡單的理解就是:在已知兩個字串的lcs的前提下,同時往兩個字串後新增乙個字元,如果該兩字元相等,則說明新的字串對的lcs長度為 原lcs長度值加1。如果給兩個字元不相等,向上、向左相鄰的lcs值中兩者較大值。向左(或向上)相鄰的lcs值 等價於 在已知兩個字串的lcs值前提下,向其中乙個字串新增乙個字母,那麼新的lcs值就有兩種可能,要麼不變,要麼加1。
int longestcommonsubsequence(string text1, string text2)
} // dp table最後乙個位置即為lcs值。
int lcs = dp[length_t1][length_t2];
return lcs;
}
最長公共子串行 動態規劃
經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所...
最長公共子串行 動態規劃
關於用動態規劃法求兩個序列的最長公共子串行問題的相關知識見 王曉東 計算機演算法設計與分析 第三章。注意,這裡所指的最長公共子串行是可以不相鄰的,與平常所說的最長公共子串 相鄰的 不一樣。直接上 lcs.h ifndef lcs h define lcs h class lcstring endif...
最長公共子串行(動態規劃)
定義 乙個數列 如果分別是兩個或多個已知數列的子串行,且是所有符合此條件序列中最長的,則 稱為已知序列的最長公共子串行。考慮最長公共子串行問題如何分解成子問題,設a a0,a1,am 1 b b0,b1,bm 1 並z z0,z1,zk 1 為它們的最長公共子串行。不難證明有以下性質 1 如果am ...