この質問は動的プログラミングにおける非常に古典的な質問で、2 つの文字列の中で最も長い共通部分文字列を見つけて、その最大長または最大文字列を返します。
1. 問題解決のアイデア
2 つの文字列を 2 次元行列の行と列として使用し、2 次元行列の各点に対応する行文字列と列文字列の文字が同じかどうかを比較できます。同様の場合は 1 に設定され、それ以外の場合は 0 に設定されます。次に、それを解決するには、値 1 を持つ最長の対角線を見つけるだけで済みます。
たとえば、次の 2 つの文字列の場合:
str1="asdfas"
str2="werasdfaswer"
探している共通部分文字列は図内のいくつかの対角線であり、長い共通部分文字列は最も長い対角線を持つものであることがわかります。
2. 動的プログラミング
動的プログラミングの核心は、転送方法、前のステップの結果の使用方法、および現在の状態の結果を取得するために現在の条件に従って判断する方法です。
record[i][j]=1可以演变为record[i][j]=1+record[i-1][j-1]
3. この関数は、最長の共通部分文字列の長さを出力することを実現します。
def lcs_max_num(str1, str2):
m = len(str1)
n = len(str2)
max_num = 0
# 构造一个(m+1)*(n+1)的二维数组来存储LCS的长度
lcs_len = [[0] * (n + 1) for i in range(m + 1)]
# 动态规划求解LCS的长度
for i in range(1, m + 1):
for j in range(1, n + 1):
if str1[i - 1] == str2[j - 1]:
lcs_len[i][j] = lcs_len[i - 1][j - 1] + 1
if max_num < lcs_len[i][j]:
max_num = lcs_len[i][j]
return max_num
if __name__ == "__main__":
str1 = 'asdfas'
str2 = 'werasdfaswer'
print(lcs_max_num(str1, str2))
4 番目に、この関数は最長の共通部分文字列の出力を実現します。
def lcs_max_char(str1, str2):
m = len(str1)
n = len(str2)
# 构造一个(m+1)*(n+1)的二维数组来存储LCS的长度
lcs_len = [[0] * (n + 1) for i in range(m + 1)]
# 动态规划求解LCS的长度
for i in range(1, m + 1):
for j in range(1, n + 1):
if str1[i - 1] == str2[j - 1]:
lcs_len[i][j] = lcs_len[i - 1][j - 1] + 1
else:
lcs_len[i][j] = max(lcs_len[i - 1][j], lcs_len[i][j - 1])
# 根据LCS的长度求解LCS的文本
lcs_text = ""
i = m
j = n
while i > 0 and j > 0:
if str1[i - 1] == str2[j - 1]:
lcs_text = str1[i - 1] + lcs_text
i -= 1
j -= 1
elif lcs_len[i - 1][j] > lcs_len[i][j - 1]:
i -= 1
else:
j -= 1
return lcs_text
if __name__ == "__main__":
str1 = 'asdfas'
str2 = 'werasdfaswer'
print(lcs_max_char(str1, str2))