動態規劃之最長公共子串行 最長公共子串

2021-08-16 00:16:45 字數 1949 閱讀 8379

題目

如果字串1的所有字元按其在字串中的順序出現在另外乙個字串2中,則字串1稱之為字串2的子串行。

注意,並不要求子子串行(字串1)的字元必須連續出現在字串2中。

請編寫乙個函式,輸入兩個字串,求它們的最長公共子串,並列印出最長公共子串行。

例如:輸入兩個字串bdcaba和abcbdab,字串bcba和bdab都是是它們的最長公共子串行,則輸出它們的長度4,並列印任意乙個子串行。

分析本問題是典型的動態規劃問題,子字串的最優解為字串提供了決策依據。有兩個字串str1和str2,設c[i,j]為子串str1[0-i]和str2[0-j]的最長公共子串行的長度,

如果str1[i]=str2[j],則c[i,j]=c[i-1,j-1]+1;

如果str1[i]!=str2[j],則c[i,j]要麼等於str1[0,i-1]和str2[0,j]的最長公共子串行的長度,要麼等於str1[0,i]和str2[0,j-1]的最長公共子串行的長度,取兩者的最大值即是c[i,j]

如圖乙個示例

狀態轉移方程:

c[0,j]=0;

c[i,0]=0;

c[i,j]=c[i-1,j-1]+1, 若str1[i]=str2[j];

c[i,j]=max

**

1

int lcslen(char* stra,char* strb,int**c)

2else

1417}18

}1920return

c[len_a][len_b];21}

2223

void lcs(char* stra,char*strb)

2434

35int k=lcslen(stra,strb,c);

3637

char* lcs=new

char

[k];

3839

int i=len_a+1;40

int j=len_b+1;41

while(k>=0)42

else

if(c[i][j]==c[i-1

][j])

47else

if(c[i][j]==c[i-1][j-1

])5055}

5657

for (int i=0;i<=len_a;i++)

5861

delete

c;62 }

動態規劃之最長公共子串

本題和上題的區別是子串要求是連續的。那麼當str1[i]!=str2[j]的時候,前面的公共子串到此結束,c[i,j]重新等於0,開始尋找下乙個公共子串。

狀態轉移方程式變為:

c[0,j]=0;

c[i,0]=0;

c[i,j]=c[i-1,j-1]+1, 若str1[i]==str2[j];

c[i,j]=0, 若str1[i]!=str2[j]

最大子串長度max_dis=max

**

1

int continuouslcs(char* stra,char*strb)215

16int max_dis=0,index=0;17

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

18else

2528

29if (max_dis<=c[i][j])

3034}35

36}3738

//output result

39for (int i=index-max_dis;i)

4043 cout<

4445

//free

46for (int i=0;i<=len_a;i++)

4750

delete

c;51

52return

max_dis;

53 }

複雜度為

θ(mn)

動態規劃之最長公共子串行

最長公共子串行簡介 舉例說明並分析 塊測試結果 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列,確切的說,若給定序列x 則另一串行z x的子串行是指存在乙個嚴格的下標序列,使得對於所有的j 0,1,k 1有zj xij。例如序列z 是序列x 的子串行,相應的遞增下標序列維。最長公共子串行問...

動態規劃之最長公共子串行

給出兩個字串,求出這樣的一 個最長的公共子串行的長度 子串行 中的每個字元都能在兩個原串中找到,而且每個字元的先後順序和原串中的 先後順序一致。sample input abcfbc abfcab programming contest abcd mnp sample output 4 2 0對於動...

動態規劃之最長公共子串行

最長公共子串行問題 time limit 1000 ms memory limit 65536 kib submit statistic discuss problem description 給定兩個序列x input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文...