我一直在寻找像疯了似的一个解释的差异算法的工作,是有效的。

最近我得到的是 这个链接到RFC3284 (从几个埃里克散的博客),其中描述了在完全可以理解的条款 数据格式 在其中的差异的结果被存储。然而,它没有提及任何如何计划将达到这些结果,同时做一个差异。

我试着研究出这个人好奇,是因为我敢肯定还有必须权衡当实现的差异算法,这是很清楚的,有时候当你看着差异,并想知道"我为什么没有差异的程序选择了这样一个改变,而不是吗?"...

我在哪里可以找到一个描述中的一个有效的算法,这最终会输出VCDIFF?
顺便说一句,如果您要找到一个说明实际使用的算法SourceGear的DiffMerge,这会更好。

注:最常见的子序列似乎并不是的算法所使用的VCDIFF,它看起来像他们在做什么聪明,鉴于数据格式,他们使用。

有帮助吗?

解决方案

O(ND)差异算法及其变体是一篇精彩的论文,您可能需要从那里开始。它包括伪代码和执行差异所涉及的图遍历的可视化。

第4节引入了对算法的一些改进,使其非常有效。

成功实施此功能将为您提供工具箱中非常有用的工具(也可能是一些非常好的经验)。

生成所需的输出格式有时会很棘手,但如果您对算法内部有了解,那么您应该能够输出所需的任何内容。您还可以引入启发式方法来影响输出并进行某些权衡。

这是一个页面,其中包含一些文档,完整源代码,以及使用上述算法中的技术的diff算法示例。

源代码似乎与基本算法密切相关,易于阅读。

还有一些准备输入,你可能会觉得有用。当您按字符或标记(单词)进行区分时,输出会有很大差异。

祝你好运!

其他提示

我首先看一下diff的实际源代码,GNU使可用

对于理解该源代码的实际工作原理,该软件包中的文档引用了启发它的论文:

  

基本算法在“An O(ND)差分算法及其变体”,Eugene W.Myers,'Algorithmica'Vol。 1986年第1号,第251-266页;并在“文件”中   比较计划“,Webb Miller和Eugene W. Myers,'软件 - 实践与经验'卷。 15 No. 11,1985,pp.1025-1040。该算法是独立发现的,如“Algorithms for Approximate String Matching”,E.Ukkonen,`Information and Control'Vol。 64,1985,pp.100-118。

阅读论文然后查看实现的源代码应该足以理解它是如何工作的。

请参阅 https://github.com/google/diff-match-patch

  

“Diff Match和Patch库   提供强大的算法来执行   同步所需的操作   纯文本。 ...目前可用   在Java,JavaScript,C ++,C#和   蟒"

另请参阅 wikipedia.org差异页面和 - " Bram Cohen:差异问题已经解决了"

我来这里寻找的差异算法和随后我自己的执行。对不起我不知道vcdiff.

维基百科:从长共同的子序列的这只是一个小的步骤以获得比较像产出:如果一个项目是不存在的子序列,但本在原始的,它必须已经删除。(《'–'标记,下面。) 如果是不存在的子序列,但在第二个序列,它必须已经增加。(《'+'标记。)

漂亮的画的 LCS算法在这里.

链接到一个快速的 LCS红宝石实施这里.

我的缓慢和简单的红宝石的适应是如下。

def lcs(xs, ys)
  if xs.count > 0 and ys.count > 0
    xe, *xb = xs
    ye, *yb = ys
    if xe == ye
      return [xe] + lcs(xb, yb)
    end
    a = lcs(xs, yb)
    b = lcs(xb, ys)
    return (a.length > b.length) ? a : b
  end
  return []
end

def find_diffs(original, modified, subsequence)
  result = []
  while subsequence.length > 0
    sfirst, *subsequence = subsequence
    while modified.length > 0
      mfirst, *modified = modified
      break if mfirst == sfirst
      result << "+#{mfirst}"
    end
    while original.length > 0
      ofirst, *original = original
      break if ofirst == sfirst
      result << "-#{ofirst}"
    end
    result << "#{sfirst}"
  end
  while modified.length > 0
    mfirst, *modified = modified
    result << "+#{mfirst}"
  end
  while original.length > 0
    ofirst, *original = original
    result << "-#{ofirst}"
  end
  return result
end

def pretty_diff(original, modified)
  subsequence = lcs(modified, original)
  diffs = find_diffs(original, modified, subsequence)

  puts 'ORIG      [' + original.join(', ') + ']'
  puts 'MODIFIED  [' + modified.join(', ') + ']'
  puts 'LCS       [' + subsequence.join(', ') + ']'
  puts 'DIFFS     [' + diffs.join(', ') + ']'
end

pretty_diff("human".scan(/./), "chimpanzee".scan(/./))
# ORIG      [h, u, m, a, n]
# MODIFIED  [c, h, i, m, p, a, n, z, e, e]
# LCS       [h, m, a, n]
# DIFFS     [+c, h, +i, -u, m, +p, a, n, +z, +e, +e]

根据Emmelaich给出的链接,在 Neil Fraser的网站上也有很大的差异化策略。 (图书馆的一位作者)

他介绍了基本策略,并在文章的最后进展到Myer的算法和一些图论。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top