耐心差异 - 在非独特线路的最后阶段究竟做了什么?

时间:2012-04-19 14:58:50

标签: algorithm diff

我有一个基于最长增长子序列的算法,当每个集合中的对象都是唯一的时,它非常适合解决相关的业务问题,但当两个集合中存在许多非唯一对象时,往往会产生奇怪的结果。

使用Patience Diff算法(也基于最长增加子序列)的方法似乎可以提供非特殊对象存在时所需的结果。然而,在我弄清楚Patience Diff是否合适之前,为了将它应用于我的问题,如果它适合,我需要更好地理解算法。

我理解步骤1到3中会发生什么,但我不清楚步骤4中发生了什么。在1到3之后,现在仍然存在无法匹配的唯一行块和非唯一行。那么接下来会发生什么 - 假设与文档的剩余第一行/最后一行不匹配,肯定它不会终止(因为没有更多的唯一行)?或者它是否将一个文档中的每个非唯一块与另一个文档中的每个非唯一块进行比较,并以某种方式选择最佳匹配?

http://bramcohen.livejournal.com/73318.html

  1. 如果它们相同则匹配两者的第一行,然后匹配第二行,第三行等,直到一对不匹配。
  2. 匹配两者的最后几行,如果它们相同,则匹配倒数第二行,倒数第二行等,直到一对不匹配为止。
  3. 查找两侧恰好出现一次的所有行,然后在这些行上执行最长的公共子序列,将它们匹配起来。
  4. 在匹配行之间的每个部分执行步骤1-2

1 个答案:

答案 0 :(得分:2)

一旦你用完了独特的线条,你需要回到不同的对齐算法。 Git在那时使用标准差异算法(Eugene Myers的O(ND)算法)。

例如,如果这两个文件是:

a 12121 e 1212 b ee c x d
a 21212 e 2121 b ye c d

首先,耐心算法会对齐任何唯一且存在于两个文件中的行:

a b c d
a b c d

然后递归对齐这些行之间的每个子范围,首先再次执行耐心算法,然后在耐心算法与任何事物都不匹配时执行LCS算法。

1212 e 121    |  ee  |    x
2121 e 2      |  ye  |

在第一个子范围中,e现在两者都是唯一的,因此第二个耐心差异传递将对齐它,将其分成两个新的子范围。新的第一个子范围(12121 vs 21212)没有任何唯一的行,因此它将与LCS算法对齐。第二个新的子范围(1212 vs 2121)是通过LCS算法的第二次传递完成的。

上面的第二个分组(ee vs ye)没有任何唯一的线条,因此它们也将使用LCS算法进行对齐。

最后的分组(x vs nothing)只输出x作为删除,而不用耐心或LCS算法。