Algorithm 耐心差异-对于非唯一线路,在最后阶段具体做了什么?

Algorithm 耐心差异-对于非唯一线路,在最后阶段具体做了什么?,algorithm,diff,Algorithm,Diff,我有一个基于最长递增子序列的算法,当每个集合中的对象都是唯一的时,该算法可以很好地解决相关的业务问题,但当两个集合中都存在许多非唯一的对象时,它往往会给出奇怪的结果 当存在非唯一对象时,使用Patience Diff算法(也基于最长递增子序列)的方法似乎可以提供我想要的结果。然而,在我能够确定Patience Diff是否合适之前,为了将它应用到我的问题中,如果它合适的话,我需要对算法有更好的理解 我理解第1步到第3步会发生什么,但我不清楚第4步会发生什么。在1到3之后,现在仍然存在没有可能匹配

我有一个基于最长递增子序列的算法,当每个集合中的对象都是唯一的时,该算法可以很好地解决相关的业务问题,但当两个集合中都存在许多非唯一的对象时,它往往会给出奇怪的结果

当存在非唯一对象时,使用Patience Diff算法(也基于最长递增子序列)的方法似乎可以提供我想要的结果。然而,在我能够确定Patience Diff是否合适之前,为了将它应用到我的问题中,如果它合适的话,我需要对算法有更好的理解

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

  • 如果两行的第一行相同,则匹配第二行、第三行等,直到一对不匹配
  • 如果两行的最后一行相同,则将其匹配,然后将下一行与最后一行、第二行与最后一行等匹配,直到一对不匹配为止
  • 找到两边正好出现一次的所有直线,然后在这些直线上执行最长的公共子序列,将它们匹配起来
  • 在匹配线之间的每个截面上执行步骤1-2

  • 一旦你用完了唯一的线,你需要回到一个不同的对齐算法。Git在这一点上使用标准的diff算法(Eugene Myers'O(ND)算法)

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

    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对21212)没有任何唯一的行,因此它将与LCS算法对齐。第二个新的子范围(1212对2121)通过LCS算法的第二次传递完成

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


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

    从源代码看,似乎不像在整个非唯一行上运行LCS那么简单。他们将一些线路分组,做一些LCS,然后回去做其他事情,然后再次回到LCS。无论如何,对于我正在处理的特定问题,我最终提出了一种启发式方法,对于正在处理的特定类型的数据,这种方法更简单(可能)更有效。@Gigatron:您不会同时在所有非唯一行上运行LCS。Patience Diff将为您提供唯一行的对齐方式,然后您在该对齐方式内的每个非唯一行范围上进行LCS。如何为非唯一行上的LCS运行选择范围?如果文档1中有4个这样的范围,文档2中有5个这样的范围,那么我是否会针对其他5个范围分别运行LCS(从而运行20个LCS),然后选择子序列最长的范围对?@Gigatron:很难用注释来描述,因此我用一个示例更新了我的答案。