算法之路__19、動態規劃之最長公共子序列

動態規劃之最長公共子序列

問題描述

序列可以理解成一個字符串,
比如『Chinese』就是一個序列,而子序列指的是由序列中的若干字符,
按原相對次序構成的序列。需要注意的是,子序列中的各個字符的相對次序一定和原來序列中的相對次序一樣。
比如,『Cin』是『Chinese』的子序列,而『sin』就不是『Chinese』的子序列。
最長公共子序列(Longest Common Subsequence)問題,
就是要找出兩個序列的最長的公共子序列。
假設有一個長度爲n的序列A[1,n]和一個長度爲m的序列B[1,m],A和B的最長公共子序列可以記爲LCS(A, B)。

思路

對於序列A[0,n]和B[0,m],LCS(A, B)無非三種情況:
1.若n=-1或m=-1,則取作空序列("");
2.若A[n] = 'X' = B[m],則取作LCS(A[0,n-1], B[0,m-1]) + 'X';
3.若A[n] ≠ B[m],則取在LCS(A[0,n], B[0,m-1])和LCS(A[0,n-1], B[0,m])中取更長者。
def getLCS(str1, str2):
    str1_len = len(str1)
    str2_len = len(str2)
    c = [[0 for i in range(str2_len+1)] for i in range(str1_len+1)]  # 創建一個二維數組,記錄最長公共子序列的長度
    lcs = ''  # 記錄當前得到的子序列
    for i in range(1, str1_len + 1):
        haveSame = False  # 記錄當前行有沒有相同的字符,如果有,則將該變量置爲True
        sameChar = ''  # 記錄當前行相同的字符
        for j in range(1, str2_len + 1):
            if str1[i-1] == str2[j-1]:
                c[i][j] = c[i-1][j-1] + 1
                haveSame = True
                sameChar = str1[i-1]
            else:
                c[i][j] = c[i][j-1] if c[i][j-1] > c[i-1][j] else c[i-1][j]
        if haveSame and c[i][j] == len(lcs) + 1:
            lcs += sameChar
    return lcs

str1 = 'didactiC'
str2 = 'advant'
print(getLCS(str1, str2))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章