Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 差分算法?_Algorithm_Diff_Vcdiff - Fatal编程技术网

Algorithm 差分算法?

Algorithm 差分算法?,algorithm,diff,vcdiff,Algorithm,Diff,Vcdiff,我一直在疯狂地寻找一个有效的diff算法的解释 我得到的最接近的是(来自Eric Sink的几篇博客文章),它用完全可以理解的术语描述了存储差异结果的数据格式。然而,它并没有提到一个程序如何在进行差异化时达到这些结果 出于个人好奇心,我试图对此进行研究,因为我确信在实现diff算法时必须进行权衡,这一点有时在您查看diff时非常清楚,并想知道“为什么diff程序选择这个作为更改而不是那个?” 在哪里可以找到最终输出VCDIFF的高效算法的描述? 顺便说一下,如果您碰巧找到SourceGear的D

我一直在疯狂地寻找一个有效的diff算法的解释

我得到的最接近的是(来自Eric Sink的几篇博客文章),它用完全可以理解的术语描述了存储差异结果的数据格式。然而,它并没有提到一个程序如何在进行差异化时达到这些结果

出于个人好奇心,我试图对此进行研究,因为我确信在实现diff算法时必须进行权衡,这一点有时在您查看diff时非常清楚,并想知道“为什么diff程序选择这个作为更改而不是那个?”

在哪里可以找到最终输出VCDIFF的高效算法的描述?
顺便说一下,如果您碰巧找到SourceGear的DiffMerge使用的实际算法的描述,那就更好了


注意:最长的公共子序列似乎不是VCDIFF使用的算法,考虑到他们使用的数据格式,看起来他们正在做一些更聪明的事情。

我首先要看一下GNU制作的diff的实际源代码

为了了解源代码的实际工作原理,该包中的文档参考了启发源代码的论文:

基本算法在“O(ND)差分算法及其变体”中进行了描述,Eugene W.Myers,“Algorithmica”第1卷第2期,1986年,第251-266页;在“文件”中 “比较程序”,韦布·米勒和尤金·迈尔斯,“软件——实践与体验”第15卷第11期,1985年,第1025-1040页。该算法是按照“近似字符串匹配算法”中的描述独立发现的,E.Ukkonen,`信息与控制'第64卷,1985年,第100-118页

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

是一篇精彩的论文,您可能想从这里开始。它包括伪代码和一个很好的图形遍历可视化,这些图形遍历涉及到执行diff

本文第4节对算法进行了一些改进,使其非常有效

成功实现这一点将为您的工具箱中留下一个非常有用的工具(可能还有一些优秀的经验)

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

这包括一些文档,以及使用上述算法中的技术的diff算法的示例

该算法似乎严格遵循基本算法,易于阅读

还有一点是关于准备输入的,您可能会发现这很有用。当您按字符或标记(单词)进行扩散时,输出会有巨大的差异

祝你好运

“差异匹配和修补程序库 提供稳健的算法来执行 同步所需的操作 纯文本…当前可用 在爪哇,JavaScript、C++、C语言和 蟒蛇“


另请参见基于Emmelaich给出的链接的和-”

,上面还有大量的差异策略


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

我来这里寻找diff算法,然后自己实现。对不起,我不知道vcdiff

:从最长的公共子序列中,获得类似于diff的输出只需一小步:如果子序列中不存在项,但原始序列中存在项,则该项必须已被删除。(下面的“-”标记)如果在子序列中不存在,但在第二个序列中存在,则必须将其添加到。(使用“+”标记。)

很好的动画效果

链接到fast

下面是我缓慢而简单的ruby改编

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]
def lcs(xs,ys)
如果xs.count>0和ys.count>0
xe,*xb=xs
ye,*yb=ys
如果xe==ye
返回[xe]+lcs(xb,yb)
结束
a=lcs(xs,yb)
b=lcs(xb,ys)
返回(a.长度>b.长度)?a:b
结束
返回[]
结束
def查找差异(原始、修改、后续)
结果=[]
而subsequence.length>0
sfirst,*子序列=子序列
修改时。长度>0
mfirst,*修改=修改
如果mfirst==sfirst,则中断
结果0
首先,*原件=原件
如果ofirst==sfirst,则中断

结果简而言之,Hmmm有时从实际的源代码中找出底层算法(特别是如果它被优化为高效的话)会非常复杂。我将能够一步一步地理解这个程序在做什么,但不能确切地理解“为什么”,也不能从高层次上了解它。。。示例:通过查看Perl正则表达式的实现,您永远不会理解正则表达式是如何工作的(或它们是什么)。或者,如果你能做到这一点,那么我想,我肯定需要一个更详细、更高层次的概述来了解到底发生了什么。我从来都不理解绝大多数Perl是如何工作的:-),但是包文档中有一个链接(见更新)会指向描述它的文献(它是diff算法,而不是Perl).不要读密码。阅读这篇文章。我只是想提一下科恩的算法似乎也被称为Patience Diff。它是bazaar中的(默认?)Diff算法,是git中的可选算法。维基百科上没有?您可以尝试用高级语言(如python)找到另一个实现,它可能比C实现更容易理解。Python以易于阅读而闻名?python中有一个difflib。这是指向源的url。该消息来源对diff算法有大量评论。RFC不是用来描述算法的。它们旨在描述接口(/协议)