寻找最长的共同序列

时间:2014-12-21 15:46:25

标签: algorithm

我正在阅读文章,找到两个给出字符串之间最长的共同点。

我开始了解一个代码如下的算法:

for(int i=0;i<=n;i++)
    for(int j=0;j<=m;j++){

        if(i==0 || j==0) dd[i][j]=0;
        else if(a[i-1]==b[j-1])
            dd[i][j] = 1 + dd[i-1][j-1];
        else{
            dd[i][j] = Math.max(dd[i-1][j], dd[i][j-1]);
        }
    }

我不理解这一点,但我无法理解它是如何工作的,即正确工作的证据是什么。为什么这个东西工作请帮我理解算法

2 个答案:

答案 0 :(得分:1)

如果你谷歌,你可以找到很多资源..

这是来自第一个链接[Word Aligned]。动画有很好的解释

答案 1 :(得分:0)

让,

str1 = "bcd"
str2 = "dabc"

此处n=3m=4

The outer loop is for str1 and inner loop is for str2
  • 第一次迭代用于初始化数组。

以下是dd数组的第一眼:

0, 0, 0, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 0, 0
  • 在外循环的第二次迭代中,它将整个str2与str1的第一个字符进行比较,即"dabc" with 'b'

现在当'b'"dabc"进行比较时,我们发现在第4次迭代时会有匹配,因此数组值将相对于当前位置的角值进行更改。当前位置为[1][3]。由于角([0][2])值为0,因此当前值为1

0, 0, 0, 0, 0
0, 0, 0, 1, 0
0, 0, 0, 0, 0
0, 0, 0, 0, 0

在迭代结束时,数组将如下所示:

0, 0, 0, 0, 0
0, 0, 0, 1, 1
0, 0, 0, 0, 0
0, 0, 0, 0, 0

位置[1][4]的值已更改,因为如果str2的字符与str1的当前字符不匹配,则当前位置的值将为当前位置的上下位置之间的最大值。这里的最大值是1

现在检查一下,如果str1="b"最大匹配为1,那么我们计算每次迭代中str1的每个条目的最大匹配。

  • 在外循环的第3次迭代中,它将整个str2再次与str1的第2个字符进行比较,即"dabc" with 'c'

现在在第5次迭代时会有一个匹配,因此数组值将相对于当前位置的角值进行更改。当前位置为[2][4]。由于角([1][3])值为1,因此当前值为2

0, 0, 0, 0, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 0, 0

现在检查一下,如果str1="bc"最大匹配为2,那么我们计算每次迭代中str1的每个条目的最大匹配。

在迭代结束时,数组将如下所示:

0, 0, 0, 0, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 0, 0
  • 在外循环的第4次迭代中,它将整个str2再次与str1的第3个字符进行比较,即"dabc" with 'd'

现在在第二次迭代时会有一个匹配,因此数组值将相对于当前位置的角值进行更改。当前位置为[3][1]。由于角([2][0])值为0,因此当前值为1

0, 0, 0, 0, 0
0, 0, 0, 1, 0
0, 0, 0, 0, 2
0, 1, 0, 0, 0

不会再进行匹配。

在迭代结束时,数组将如下所示:

0, 0, 0, 0, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 1, 1, 1, 2

所以这两个字符串的LCS是dd[3][4] = 2

希望你明白这一点。您也可以从here

获得帮助

注意:这里我只介绍匹配情况。如果str2中的一个字符与str1的当前字符不匹配,则当前位置的值将是当前位置的上左位置之间的最大值。亲自尝试一下,你会理解为什么我们这样做:)