經典演算法學習 動態規劃 最長公共子串行

2021-07-10 11:35:45 字數 2774 閱讀 1609

前幾天做筆試題,遇到最長遞增子串行的問題,不知怎麼解,看網上有一種先將該序列排序,以轉化為求新序列與原有序列的最長公共子串。然而,最長公共子串行也!不!會!

這兩個演算法在大學時都應該是接觸過的,到此時居然已經忘的一乾二淨,才知道自己究竟差了多少功夫。於是先學一下最長公共子串行的解法,在這裡記下來,待下次再不會做時也好有個查閱的好地方。最長遞增子串行的解法改天再學。

設有字串a,b。

記a(0,i)為a從0位到i位的子串。

使用二維陣列c來記錄最長公共子串行長度,c[i][j]表示a(0,i)與b(0,j)的最長公共子串行長度。設c[-1][j] = c[i][-1] = 0,不論 i,j 取何值。

動態規劃的思路如下:

1)若a[i] == b[j],則c[i][j] = c[i-1][j-1] + 1

2)若a[i] != b[j],則c[i][j] = max

在其後構造最長公共子串行時,則逆向使用求最長公共子串行長度時的資料。首先初始化空的字串。

從表c右下角開始迴圈,記c[i][j],每次在下列三個表項中查詢最大值

a) c[i-1][j]

b) c[i][j-1]

c) c[i-1][j-1]

若a)最大,則令 i = i - 1

若b)最大,則令 j = j - 1

若c)最大,則在字串前插入a[i]的字元,而後令 i = i - 1,j = j - 1

其中可能出現 a),b) 兩數值相等,則說明有兩種構造最長公共子串行的方式,這兩種子串行可能相同,也可能不同。

為了簡化這個過程,也可以構造二維陣列d,來儲存構造最長公共子串行時,i,j 的調整方向。

二維陣列c的示意圖如下,來自演算法導論第三版。

寫練習**如下,未仔細推敲,大致應該或許沒有錯…

public

class

lcs

public

intcallength(string a, string b)

else

else

if(lengthtab[i-1][j] < lengthtab[i][j-1])

else}}

}// system.out.println("lengthtab:");

// printtab(lengthtab);

// system.out.println("directtab:");

// printtab(directtab);

return lengthtab[lena-1][lenb-1];

}public string getlcs(string a, string b)

//檢驗directtab行數和列數是否與字串長度匹配

if(directtab.length != a.length() + 1)

return

""; if(directtab.length <= 0 || directtab[0].length != b.length() + 1)

return

""; int lena = directtab.length - 1;

int lenb = directtab[0].length - 1;

//在表中查詢使匹配長度最大的路線(其中一條)

while(lena > 0 && lenb > 0)

//若此最大匹配子串的構造中,不包含a.charat(lena-1),尋找下乙個包含在子串中的字元

else

if(directtab[lena][lenb] == this.top)

else

if(directtab[lena][lenb] == this.left)

else

}return sb.tostring();

}public

void

printtab(int tab)

system.out.println();}}

private

int lengthtab = null;

private

int directtab = null;

//表示這乙個單元的最大匹配長度是從上一行同一列獲得

public

static

final

int top = -1;

//表示這乙個單元的最大匹配長度是從前一列同一行獲得

public

static

final

int left = 0;

//表示這乙個單元的最大匹配長度是左上角單元數值加1獲得

public

static

final

int top_and_left = 1;

//表示這乙個單元的最大匹配長度同其左側及上方的單元都一樣,

//top_or_left原為找到所有最長公共子串行而設,在這個例子中沒有實際使用,也未經測試是否有效,

//為避免有不同路徑的相同匹配子串行,可使用treeset等集合返回查詢結果,

//但需要注意轉殖方法,以及string類的comparable介面實現情況。

public

static

final

int top_or_left = 2;

}

動態規劃經典 最長公共子串行

最長公共子串行 時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述 咱們就不拐彎抹角了,如題,需要你做的就是寫乙個程式,得出最長公共子串行。tip 最長公共子串行也稱作最長公共子串 不要求連續 英文縮寫為lcs longest common subsequence 其定義是,乙個...

動態規劃經典示例 最長公共子串和最長公共子串行

動態規劃經典示例 最長公共子串和最長公共子串行 舉例 str1 ghj8675fds str2 j86fdhl 最長公共子串是 j86 最長公共子串行是 j86fd 最長公共子串 dp i j 表示子串str1 0 i 和子串str 0 j 的最長公共子串 當str1 i str2 j 時,dp i...

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

有兩個字串 可能包含空格 請找出其中最長的公共連續子串,輸出其長度。長度在1000以內 例如 輸入 abcde bcd 輸出 3 1 把兩個字串分別以行和列組成乙個二維矩陣。2 比較二維矩陣中每個點對應行列字元中否相等,相等的話值設定為1,否則設定為0。3 通過查詢出值為1的最長對角線就能找到最長公...