Algorithm 打印最长的公共序列
我试图实现经典问题的解决方案,但我感到困惑,因为我得到了一些我没有找到好结果的案例 输出:“最长公共序列”、“长度” 对于第一种情况:Algorithm 打印最长的公共序列,algorithm,python,data-structures,Algorithm,Python,Data Structures,我试图实现经典问题的解决方案,但我感到困惑,因为我得到了一些我没有找到好结果的案例 输出:“最长公共序列”、“长度” 对于第一种情况: x= "AGGTAB" y= "GXTXAYB" print longestCommonSeq(x,y) 结果:('GTAB',4) 这是对的 但对于类似的情况: a= "APBCADCQER" b= "RASBTAUCVE" print longestCommonSeq(a,b) ('', 5) 我错过了什么?谁能给我一个提示吗?你把桌子造错了;您应
x= "AGGTAB"
y= "GXTXAYB"
print longestCommonSeq(x,y)
结果:('GTAB',4)
这是对的
但对于类似的情况:
a= "APBCADCQER"
b= "RASBTAUCVE"
print longestCommonSeq(a,b)
('', 5)
我错过了什么?谁能给我一个提示吗?你把桌子造错了;您应该将行保留在
i=0
处,将列保留在j=0
处,并将匹配项放在较高的行中。这意味着您需要将1添加到第一个循环中的i
和j
坐标中,因为Python从0开始索引
因此,您将得到一个末尾为0的表;使用类似于的符号,您基本上可以构建以下内容:
┌─┬─────┬─────────┬─────────┬─────┬──────┬───────┬─┐
│ │A │G │G │T │A │B │ │
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│G│< ^ 0│\ G │\ G │< G │< G │< G │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│X│< ^ 0│^ G │< ^ G │< ^ G│< ^ G │< ^ G │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│T│< ^ 0│^ G │< ^ G │\ GT │< GT │< GT │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│X│< ^ 0│^ G │< ^ G │^ GT │< ^ GT│< ^ GT │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│A│\ A │< ^ A | G│< ^ A | G│^ GT │\ GTA │< GTA │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│I│^ A │< ^ A | G│< ^ A | G│^ GT │^ GTA │< ^ GTA│0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│B│^ A │< ^ A | G│< ^ A | G│^ GT │^ GTA │\ GTAB │0│
├─┼─────┼─────────┼─────────┼─────┼──────┼───────┼─┤
│ │0 │0 │0 │0 │0 │0 │0│
└─┴─────┴─────────┴─────────┴─────┴──────┴───────┴─┘
< and ^: maximum picked
\: add matching character to cell to the top left.
接下来,您不需要在第二个循环中查阅x
和y
,只查阅LCS
表。因为最后一行和最后一列总是以0
结束,所以当x
和y
的最后一个字符不匹配时,算法的版本会平缓下来,而当您没有命中表中列出的LCS路径时,您只会几乎随机地递减i
和j
请注意,前两个for
循环是完全冗余的,可以删除;整个LCS
表只包含0
值,为什么要将它们设置为0
更多?Wikipedia中的伪代码使用从1到长度(包含)的循环,但是由于Python从0开始,您向长度添加1以保持长度包含,因此不需要在此处执行此操作
更正后的函数如下所示:
def longestCommonSeq(x,y):
LCS = [[0 for z in range(len(y) + 1)] for z in range(len(x) + 1)]
for i in range(len(x)):
for j in range(len(y)):
if x[i] == y[j]:
LCS[i + 1][j + 1] = 1 + LCS[i][j]
else:
LCS[i + 1][j + 1] = max(LCS[i][j + 1], LCS[i + 1][j])
res = ''
i, j = len(x), len(y)
while i and j:
if LCS[i][j] == LCS[i-1][j]:
i -= 1
elif LCS[i][j] == LCS[i][j-1]:
j -= 1
else:
res = x[i-1] + res
i -= 1
j -= 1
return res, LCS[-1][-1]
由于LCS
表现在已正确构建,因此我们也可以使用LCS[-1][1]
作为最大长度值
这将产生预期的结果:
>>> x = "AGGTAB"
>>> y = "GXTXAYB"
>>> print longestCommonSeq(x, y)
('GTAB', 4)
>>> a = "APBCADCQER"
>>> b = "RASBTAUCVE"
>>> print longestCommonSeq(a, b)
('ABACE', 5)
另一种方法是,在第二阶段将off设置为1,然后查看与输入字实际对应的LCS表格单元格;e、 g.从i
和j
中减去1:
def longestCommonSeq(x,y):
LCS = [[0 for z in range(len(y)+1)] for z in range(len(x)+1)]
for i in range(len(x)):
for j in range(len(y)):
if x[i] == y[j]:
LCS[i][j] = 1 + LCS[i - 1][j - 1]
else:
LCS[i][j] = max(LCS[i - 1][j], LCS[i][j - 1])
i, j = len(x) - 1, len(y) - 1
print LCS
res = ""
while i >= 0 and j >= 0:
if x[i] == y[j]:
res= x[i] + res
i -= 1
j -= 1
else:
if LCS[i - 1][j] > LCS[i][j - 1]:
i -= 1
else:
j -= 1
return res, LCS[len(x) - 1][len(y) - 1]
现在i
和j
的范围分别为len(x)-1
到0
和len(y)-1
到0
,您再次引用了正确的单元格
>>> x = "AGGTAB"
>>> y = "GXTXAYB"
>>> print longestCommonSeq(x, y)
('GTAB', 4)
>>> a = "APBCADCQER"
>>> b = "RASBTAUCVE"
>>> print longestCommonSeq(a, b)
('ABACE', 5)
def longestCommonSeq(x,y):
LCS = [[0 for z in range(len(y)+1)] for z in range(len(x)+1)]
for i in range(len(x)):
for j in range(len(y)):
if x[i] == y[j]:
LCS[i][j] = 1 + LCS[i - 1][j - 1]
else:
LCS[i][j] = max(LCS[i - 1][j], LCS[i][j - 1])
i, j = len(x) - 1, len(y) - 1
print LCS
res = ""
while i >= 0 and j >= 0:
if x[i] == y[j]:
res= x[i] + res
i -= 1
j -= 1
else:
if LCS[i - 1][j] > LCS[i][j - 1]:
i -= 1
else:
j -= 1
return res, LCS[len(x) - 1][len(y) - 1]