演算法題9 動態規劃之最長公共子串行 最長公共子串

2022-03-28 09:59:42 字數 2041 閱讀 2959

題目

如果字串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 }

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

題目 如果字串1的所有字元按其在字串中的順序出現在另外乙個字串2中,則字串1稱之為字串2的子串行。注意,並不要求子子串行 字串1 的字元必須連續出現在字串2中。請編寫乙個函式,輸入兩個字串,求它們的最長公共子串,並列印出最長公共子串行。例如 輸入兩個字串bdcaba和abcbdab,字串bcba和b...

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

最長公共子串行,指兩個字串,子串行中最長的字串。不一定是連續字元 最長公共子串行長度 intlcs length const string str1,const string str2,vectorint veca for j 0 j str2.length j for i 1 i str1.len...

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

動態規劃之最長公共子串行演算法 演算法思想 假設x x1,x2,xm y static void init xy void getchar for i 1 i n i getchar static void lcs length void else if c i 1 j c i j 1 else p...