diff 实现

就是用了 @smlg 提到的LCS。我用伪CoffeeScript代码翻译下吧:

首先我们把文件old、new转化为两个列表,列表的每个元素是文件的某一行:

A = [1行、2行、3行、4行、...]
B = [1行、2行、3行、4行、...]

然后我们计算A和B最长的相似元素的长度lcs(递归就是力量)

lcs = (A, B) ->
    result = 0
    if A.length is 0 or B.length is 0
        result
    else if A[0] is B[0]
        result = 1 + lcs(A[1..], B[1..])
    else
        result = Math.max(lcs(A, B[1..]), lcs(A[1..], B))

(之所以叫伪CoffeeScript,因为真实环境下,文件足够大的话,会因为递归太多而爆栈……)

拿到了lcs,然后根据计算lcs时找到的能对上的头,就可以得出两个文件最大的相同部分,用C表示,那么,A、B就被切分成了:

A-、C、A+
B-、C、B+

然后,我们再用同样的方法比较A-、B-,以及A+、B+,一直这样递归下去,一段段地比较,最后把所有的结果拼起来,diff就出炉啦~

当然,实际的算法肯定会有很多优化的,比如找lcs会用更高效的算法(动态规划什么的),中间结果的缓存等等。

还有一种diff算法是比较字与字的不同(比较适合于文档),其实也是一样的原理,只是把按行切割改成按单词或字符切割而已(当然,具体到某种语言,为了得出更有意义的结果,会有一些调整)。

时间: 2024-10-14 10:05:31

diff 实现的相关文章

diff和patch使用指南

大纲 1.概述 2.diff的用法 3.patch的用法 4.实战演练 1.概述 diff和patch是一对工具,在数学上来说,diff是对两个集合的差运算,patch是对两个集合的和运算.     diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的patch文件,即补丁文件.     patch能将diff文件运用于 原来的两个集合之一,从而得到另一个集合.举个例子来说文件A和文件B,经过diff之后生成了补丁文件C,那么着个过程相当于 A -B = C

diff和patch命令简介

diff -u 1.txt 2.txt > diff.txt -u: 使差异输出带有上下文. 1 --- 1.txt 2017-01-21 07:09:19.015472013 -0500 2 +++ 2.txt 2017-01-21 07:11:26.385045822 -0500 3 @@ -5,9 +5,9 @@ 4 全拼,双拼 5 还是五笔 6 7 -是人就有可能犯错,软件更是如此. 8 - 9 -犯了错,就要扣工资!10 -11 +诗人就有可能犯错,软件更是如此.1213 改正的成本可

Git在Windows环境下配置Diff以及Merge工具---DiffMerge

参考出处:http://coding4streetcred.com/blog/post/Configure-DiffMerge-for-Your-Git-DiffTool主要转自:http://blog.csdn.net/u010232305/article/details/51767887 1.下载DiffMerge http://sourcegear.com/diffmerge/downloads.php,楼主选择的是 Windows Installer (64bit),安装直接下一步,这一

linux常用命令--diff

diff是Unix系统的一个很重要的工具程序. 它用来比较两个文本文件的差异,是代码版本管理的基石之一.你在命令行下,输入: $ diff <变动前的文件> <变动后的文件> diff就会告诉你,这两个文件有何差异.它的显示结果不太好懂,下面我就来说明,如何读懂diff. 一.diff的三种格式 由于历史原因,diff有三种格式: * 正常格式(normal diff) * 上下文格式(context diff) * 合并格式(unified diff) 我们依次来看. 二.示例文

git diff获取差异文件中文乱码的解决办法

通过git的diff命令对两个commit id的版本进行差异化的对比.中文文件时出现乱码. git diff 6bded8d0c1fe1746c122121217dc0c88667091089 a9b87b07908a446a5471b233232ade2dbd0734d8 --name-only "markdown/2016/07/\345\210\206\346\224\257\346\265\213\350\257\225.md" 执行如下命令,修改core.quotepath

linux命令(45):diff命令

1.命令格式: diff[参数][文件1或目录1][文件2或目录2] 2.命令功能: diff命令能比较单个文件或者目录内容.如果指定比较的是文件,则只有当输入为文本文件时才有效.以逐行的方式,比较文本文件的异同处.如果指定比较的是目录的的时候,diff 命令会比较两个目录下名字相同的文本文件.列出不同的二进制文件.公共子目录和只在一个目录出现的文件. 3.命令参数: -  指定要显示多少行的文本.此参数必须与-c或-u参数一并使用. -a或--text  diff预设只会逐行比较文本文件. -

几个重要的shell命令:diff patch tar find grep

diff diir_1.0/ dir_2.0/ -urNB > dir_2.0.patch u:union以合并的格式来输出文件的差异信息 r:递归的对比所有的子目录下的文件 U:将不存在的文件视为空文件 B:忽略空行引起的差异 ~/dir_1.0$ patch -p1< ../dir_2.0.patch -p1的意思是忽略补丁文件中的路径一级分量:比如补丁是在home目录生成的,home目录下有dir_1.0/ dir_2.0/两个目录. 打补丁的时候进入了dir_1.0/这个目录,我就需要

eclipse quick diff功能

Eclipse文本编辑器和Java编辑器都提供了quick diff功能.这就使得你可以快速地识别出当前所编辑文件版本和该文件的参考版本之间的不同. 如果编辑器的quick diff功能没有启用,可以打开Preferences对话框,然后在搜索框里输入"quick diff",点击"quick diff"选项后,在右边部分做相应的设置. 如果你在编辑器中做了相应的修改,则在编辑器右边的快速差别标尺的对应位置上就会出现相应的标记,你可以把鼠标放在编辑上查看相应的信息.

Linux3:more、which、find、chmod、tar、diff、grep、ps、netstat、uname

more 类似cat,不过more不是将整个文件内容从上到下显示在屏幕上的,而是以一页一页的显示方便使用者逐页阅读.more最基本的指令就是space即往下翻一页,b即往回翻一页显示,而且还有搜索字符串的功能 +n:从第n行开始显示 -n:定义屏幕大小为n行 +/pattern:在每个档案显示前搜索该字符串patern,然后从该字符串前两行之后显示 -p:通过清除窗口而不是滚屏来对文件进行换页,与-c选项相似 -s:把连续的多个空行显示为一行 -u:把文件内容中的下划线去掉 常用操作命令: En

diff两个文件夹里的东西

diff --help -x, --exclude=PAT               exclude files that match PAT 排除某个类型的文件 -u, -U NUM, --unified[=NUM]   output NUM (default 3) lines of unified context 输入行好 -N, --new-file                  treat absent files as empty 如果某个文件只在一个地方有,就把这个文件当作不存