我对python非常陌生,并且正在努力创建一个表示最长的公共子字符串的矩阵。我正在寻找这样的结果:LCS matrix
到目前为止,这是我的代码。
def compute_lcs(X, Y):
m = len(X)
n = len(Y)
# An (m) times (n) matrix
matrix = [[0] * (n) for _ in range(m)]
for i in range(1, m):
for j in range(1, n):
if X[i] == Y[j]:
if i == 0 or j == 0:
matrix[i][j] = 1
else:
matrix[i][j] = matrix[i-1][j-1]+1
else:
matrix[i][j] = 0
return matrix
b = compute_lcs('AACTGGCAG','TACGCTGGA')
for y in b:
print (y)
Current Output:
[0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 0, 2, 0, 2, 2, 2, 0]
[0, 1, 2, 1, 3, 0, 3, 3, 0]
[0, 1, 2, 0, 2, 4, 0, 0, 0]
[0, 1, 2, 0, 1, 3, 0, 0, 0]
[0, 1, 0, 3, 0, 2, 4, 1, 0]
[0, 0, 2, 1, 4, 1, 3, 5, 0]
[0, 1, 1, 0, 2, 5, 0, 0, 0]
Expected Output:
[0, 0, 0, 1, 0, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 2, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 1, 1, 0, 0, 1]
[0, 0, 1, 0, 0, 0, 2, 0, 0]
[0, 0, 0, 2, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 3, 1, 0, 0, 0]
[0, 0, 0, 0, 1, 4, 0, 0, 1]
[1, 1, 0, 0, 0, 0, 0, 1, 0]
但是,我的结果是显示错误值的矩阵。当我手动处理矩阵时,正确的输出如下所示:Correct output。我觉得我的逻辑是有道理的,我做错了什么?
谢谢大家。
答案 0 :(得分:3)
首先,为了清楚起见,longest common subsequence问题与longest common substring问题不同。您要解决的是后者。最好不要混淆两者。
第二,在适当的else
条件下,您的if
分支未对齐。
每当字符串匹配X[i] == Y[j]
时,如果索引i或j为0,我们就将矩阵元素设置为1,因为i-1或j-1在0处给出-1(不幸的是,这也是索引中最后一项的索引Python),这不是我们想要的,否则我们为更高的索引i,j> 1递增。
第三,您的循环应该从0开始而不是1,因为我们从索引中的字符串的第一个字符开始,即索引0:
def compute_lcs(X, Y):
m = len(X)
n = len(Y)
# An (m) times (n) matrix
matrix = [[0] * n for _ in range(m)]
for i in range(0, m):
for j in range(0, n):
if X[i] == Y[j]:
if i == 0 or j == 0:
matrix[i][j] = 1
else:
matrix[i][j] = matrix[i-1][j-1]+1
else:
matrix[i][j] = 0
return matrix
要获得预期输出中显示的确切矩阵,应在打印之前交换参数的顺序或转置矩阵。但是请注意,这些不是必需的(交换或转置),仅用于格式化目的:
b = compute_lcs('TACGCTGGA', 'AACTGGCAG')
for y in b:
print (y)
[0, 0, 0, 1, 0, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 2, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 1, 0, 0, 1]
[0, 0, 1, 0, 0, 0, 2, 0, 0]
[0, 0, 0, 2, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 3, 1, 0, 0, 1]
[0, 0, 0, 0, 1, 4, 0, 0, 1]
[1, 1, 0, 0, 0, 0, 0, 1, 0]