我正在编写一个差异文本工具来比较两个相似的源代码文件。
周围有很多这样的“差异”工具,但我的应该会有所改进:
如果它发现一组行在两边不匹配(即在两个文件中),它不仅应突出显示这些行,还应突出这些行中的各个更改(我在这里称之为行间比较)。
我的一些可行的解决方案的一个例子:
替代文本 http://files.tempel.org/tmp/diff_example.png
它目前所做的是采用一组不匹配的行并再次通过差异算法运行它们的单个字符,从而产生粉红色突出显示。
但是,包含“原始 2”的第二组不匹配需要更多工作:这里,添加了前两行右侧(“添加的行 a/b”),而第三行是左侧的更改版本。我希望我的软件能够检测到可能的更改和可能的新行之间的差异。
在看这个简单的例子时,我可以很容易地检测到这种情况:
使用 Levenshtein 之类的算法,我可以发现在 3 到 5 组中的所有右行中,第 5 行与左行 3 匹配得最好,因此我可以推断出添加了右侧的第 3 行和第 4 行,并执行 inter - 左行 3 和右行 5 的行比较。
到目前为止,一切都很好。但是我仍然坚持如何将其变成为此目的的更通用的算法。
在更复杂的情况下,一组不同的线条可能会在两侧添加线条,中间有一些紧密匹配的线条。这变得相当复杂:
我不仅必须将左侧的第一行与右侧的最佳行匹配,反之亦然,以此类推。基本上,我必须将左边的每一行与右边的每一行相匹配。在最坏的情况下,这可能会产生甚至交叉,因此不再容易清楚哪些行是新插入的,哪些行是刚刚更改的(注意:我不想处理这样一个块中可能移动的行,除非这实际上会简化算法)。
当然,这永远不会是完美的,但我正在努力让它变得比现在更好。任何不太理论但相当实用的建议(我不太了解抽象算法)都会受到赞赏。
更新
我必须承认我什至不明白 LCS 算法是如何工作的。我只是简单地给它输入两个字符串数组,然后输出一个不匹配的序列列表。我基本上使用这里的代码:http: //www.incava.org/projects/java/java-diff
查看代码,我发现一个函数 equal() 负责告诉算法两行是否匹配。根据 Pavel 的建议,我想知道这是否是我进行更改的地方。但是怎么做?这个函数只返回一个布尔值——而不是一个可以识别匹配质量的相对值。而且我不能简单地使用一个固定的 Levenshtein 配给来决定一条类似的线是否仍然被认为是相等的——我需要一些能够自我采用的东西来适应整个有问题的线。
所以,我基本上要说的是,我仍然不明白我将在哪里应用与不(完全)匹配的线条的相对相似性相关的模糊值。