最長公共子串行問題和動態規劃

2021-08-15 02:57:46 字數 3274 閱讀 8786

可以注意到,子串行不要求所選的字母連續,只要求是按原次序組成就好

這是和子串的乙個區別

##最長公共子串行定義

最長公共子串行(longestcommonsequence)

簡稱為lcs,下同

直觀明了,就是兩個序列的共有的子串行中最長的乙個,

此圖里就是data這乙個單詞

#解法##1. 暴力法

首先我們想到的便是把兩個序列的所有可能的子串行列舉出來,一一進行比較.

所有乙個序列的子串行的組合有 **2

n2^n

2n**種可能,而且需要m次比較.

所以時間複雜度是o(m∗2

nm*2^n

m∗2n

),空間複雜度是o(2^n);

顯然出現了 指數形式的複雜度,這是在時間和空間上無法接受的.

##2 遞迴

對於序列a[0,n] 和a[0,m];

他們的最長自序列lcs(a,b)有三種情況

這有點不好理解,其實在開始遞迴時 ,程式並不知道誰能取得更大的字串,

所以將分別對應的兩種情況都進行遞迴直到遞迴出口,(相當於將每種情況都走完)

之後把所有的情況每次都層層返回,

每次返回都進行一次比較,總是取最大的返回值,這樣就得到了更長者

當序列為空的時候,返回0;

總結下來就是如下公式

根據這個公式很容易得出遞迴版的**

#define _crt_secure_no_warnings 1

#include

#include

char a[30]

, b[30]

;int a_len, lenb;

intlcs

(int

,int);

intmain()

intlcs

(int i,

int j)

考慮演算法的複雜度

時間複雜度在最好的情況下

例如,兩個序列相等,只需要o(n)線性時間內完成,

但若在最壞的情況下,

每進行一次遞迴,就會引發新的兩個問題,

而新的兩個問題又會引發各自新的問題,

重點是在各自的問題中會出現大量重複的問題.導致時間複雜度激增.

為o($ 2^n$)

最壞情況下的遞迴例子如圖

我們提到,用遞迴解決此問題最大乙個問題就是:

當不是最優解時總會出現重複計算的遞迴

為了解決這個問題,首先想到可以用一張表存入已計算的資料,

在計算之前先查表需要計算的資料是否存在,若不存在則再計算.

這是一種以空間複雜度換取時間複雜度的做法.

出現重複遞迴的本質是在每一次遞迴的不確定性,當末序列不相同時,是向右走還是向上走是未知的.如何具體確定路徑呢?

我們可以從頭開始畫一張表

每個方塊代表問題的解

從左往右,從上到下一次將這張表填滿.規則如下

當然會出現多解和歧**的情況,但不在本問題討論之內.

這張表就表示了所有可能出現的情況,從左上角或者右下角開始進行推到,很容易得到正確的結果.而且不會重複計算

以從右下角為例

總能取出乙個最長子序列bcba

下面是**

#define _crt_secure_no_warnings 1

#include

#include

char a[

500]

, b[

500]

;char num[

501]

[501];

///記錄中間結果的陣列

char flag[

501]

[501];

///標記陣列,用於標識下標的走向,構造出公共子串行

void

lcs();

///動態規劃求解

void

getlcs()

;///採用倒推方式求最長公共子串行

intmain()

void

lcs(

)else

if(num[i]

[j -1]

>num[i -1]

[j])

else}}

}void

getlcs()

else

if(flag[i]

[j]==2)

///如果是向左標記

j--;else

if(flag[i]

[j]==3)

///如果是向上標記

i--;}

for(i = k -

1; i >=

0; i--

)printf

("%c"

, res[i]);

}

參考:

1.資料結構mooc ppt

2.

動態規劃 最長公共子串行問題

最長公共子串行問題 longest common subsequence problem 簡稱lcs問題。題目為給定兩個序列x y求它們的lcs 最長公共子串行 這裡的子串行z的定義為 z中的元素既在x中也在y中,並且他們在x y中滿足嚴格的下標為乙個增序列 假設下標從左到右依次增大 另外,不要求z...

最長公共子串行問題 動態規劃

給定兩個字串s1s2.sn和t1t2.tn。求出這兩個字串最長的公共子串行 輸入 abcicba abdkscab 輸出 abca 定義dp i j 為s1 si和t1 tj對應的lcs的長度 s1 si 1和t1 tj 1對應的公共子列有三種情況 當si 1 tj 1時,在s1 si和t1 tj的...

最長公共子串行問題(動態規劃)

time limit 1000ms memory limit 65536kb problem description 給定兩個序列x input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文本母 a,z 表示序列x和y。output 每組輸出一行,表示所求得的最長公...