最長公共子串行

2022-06-01 22:51:12 字數 1949 閱讀 1503

問題描述:

字串行的子串行是指從給定字串行中隨意地(不一定連續)去掉若干個字元(可能乙個也不去掉)後所形成的字串行。令給定的字串行x=「x0,x1,…,xm-1」,序列y=「y0,y1,…,yk-1」是x的子串行,存在x的乙個嚴格遞增下標序列,使得對所有的j=0,1,…,k-1,有xij=yj。例如,x=「abcbdab」,y=「bcdb」是x的乙個子串行。

考慮最長公共子串行問題如何分解成子問題,設a=「a0,a1,…,am-1」,b=「b0,b1,…,bm-1」,並z=「z0,z1,…,zk-1」為它們的最長公共子串行。不難證明有以下性質:

(1) 如果am-1=bn-1,則zk-1=am-1=bn-1,且「z0,z1,…,zk-2」是「a0,a1,…,am-2」和「b0,b1,…,bn-2」的乙個最長公共子串行;

(2) 如果am-1!=bn-1,則若zk-1!=am-1,蘊涵「z0,z1,…,zk-1」是「a0,a1,…,am-2」和「b0,b1,…,bn-1」的乙個最長公共子串行;

(3) 如果am-1!=bn-1,則若zk-1!=bn-1,蘊涵「z0,z1,…,zk-1」是「a0,a1,…,am-1」和「b0,b1,…,bn-2」的乙個最長公共子串行。

這樣,在找a和b的公共子串行時,如有am-1=bn-1,則進一步解決乙個子問題,找「a0,a1,…,am-2」和「b0,b1,…,bm-2」的乙個最長公共子串行;如果am-1!=bn-1,則要解決兩個子問題,找出「a0,a1,…,am-2」和「b0,b1,…,bn-1」的乙個最長公共子串行和找出「a0,a1,…,am-1」和「b0,b1,…,bn-2」的乙個最長公共子串行,再取兩者中較長者作為a和b的最長公共子串行。

求解:引進乙個二維陣列c,用c[i][j]記錄x[i]與y[j] 的lcs 的長度,b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向。

我們是自底向上進行遞推計算,那麼在計算c[i,j]之前,c[i-1][j-1],c[i-1][j]與c[i][j-1]均已計算出來。此時我們根據x[i] = y[j]還是x[i] != y[j],就可以計算出c[i][j]。

求解:引進乙個二維陣列c,用c[i][j]記錄x[i]與y[j] 的lcs 的長度,b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向。 

我們是自底向上進行遞推計算,那麼在計算c[i,j]之前,c[i-1][j-1],c[i-1][j]與c[i][j-1]均已計算出來。此時我們根據x[i] = y[j]還是x[i] != y[j],就可以計算出c[i][j]。

問題的遞迴式寫成:

回溯輸出最長公共子串行過程:

//最長公共子串行

//採用動態規劃求解

//...

#include #include #include #define ciri_(i, a) for(int i = 0; i <= a; ++i)

#define cirj_(j, b) for(int j = 0; j <= b; ++j)

const int maxn = 100;

int c[maxn][maxn], b[maxn][maxn];

int m, n;

char s1[maxn], s2[maxn];

using namespace std;

void print_(int b[maxn], int x, int y)

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

else if(c[i-1][j] >= c[i][j-1])

else

}} ciri_(i, m)

cirj_(j, n)

{ cout<

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...

最長公共子串行 最長公共子串

1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...

最長公共子串 最長公共子串行

子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...