简体中文

开发者工具·文本比较

文本差异如何查找更改的行:LCS 和 Myers 算法

· 工作原理

文本差异 算法 开发人员工作流程

两条线序列通过其匹配条目的路径连接起来
原始 ToolAcre 矢量图

解释了基于行的比较背后的最长公共子序列的想法,以及为什么迈尔斯算法使其足够快,即使在浏览器选项卡内也能立即运行。

两个文件,一个问题:哪些行幸存下来? — 帧比较是查找两个版本共有的最长行,而不是匹配行号

两个修订版未带有说明哪些行幸存的标签。 ToolAcre 首先将每个文本分割成一个有序列表,然后搜索以相同顺序出现在两个列表中的长子序列。共享脊柱之外的线条成为添加或删除,而不是猜测的修改。

结果携带双方原始的基于 1 的位置。未更改的行在每一侧都有一个数字,仅在左侧删除,仅在右侧添加。即使重复的台词给出了不止一个合理的对齐方式,这种计算也使得所显示的故事可以审查。

为什么 diff 适用于行,而不适用于字符 - 换行符上的分割如何将文本转换为可比较单元的序列以及为什么这使得散文的行为与代码不同

该实现将完整的行视为其比较单元。因此,换行边界决定了结果:存储在一行中的段落内的单字编辑会替换整行,而逐句排列的相同散文可以隔离更小的区域。

行比较不是隐藏在不同显示后面的字符分析。 `splitLines` 创建数组,LCS 表将一个行键与另一个行键进行比较。这种可预测的粒度适合源文件和配置文件,但它无法突出显示在匹配的替换中更改的确切字母。

通俗易懂的最长公共子序列 - 在五行示例中演练 LCS 思想,并展示子序列之外的所有内容如何成为插入或删除

想象左边的行 A、B、C、D、E 和右边的行 A、C、E。A、C 和 E 形成一个有序的公共子序列。 B 和 D 不在其中,因此结果报告两个删除行和三个未更改的行,而无需将删除的行与替换行配对。

该表记录了每个剩余位置对的可用最佳共享长度。重建工作是通过这些价值观向前推进的。相同的键使双方都前进;否则,较大的相邻值决定是否发出左移除或右添加。

Myers 算法以及为什么速度很重要 — 在没有公式的情况下解释如何跟踪最短的编辑脚本如何在具有数千行的文件上保持快速比较

该工作簿名为 Myers,但 `diff.js` 显式实现普通最长公共子序列动态规划。它的注释指出了不同中间的 O(n·m) 时间和内存。声称 Myers 或最短编辑图行为将用熟悉的算法替换实际发布的代码。

ToolAcre 在分配之前限制该成本。相同的前缀和后缀在线性通道中被剥离,并且不同的中间最多可以包含 2,000 行。该矩阵是 `Uint32Array`;记录的最差允许平方大约占用 16 兆字节,而不是无界的盒装值。

ToolAcre 使用 LCS 表,而不是大纲中命名的 Myers 算法

将包含“添加的搜索”、“修复的导出”和“更新的帮助”的变更日志与保留第一个和第三个条目但在最后一个条目之前插入“添加的过滤器”的修订进行比较。公共条目锚定路径,删除“固定导出”,并添加“添加的过滤器”。

该算法不会将该对称为修改行。它的行词汇只是相等、添加和删除,因此文本替换显示为一项删除后一项添加。摘要单独对这些操作进行计数,并仅当两个计数均为零时才将文本标记为相同。

为什么两个正确的差异可能看起来不同 - 显示同样短的编辑脚本之间的联系如何解释为什么一个工具归咎于空行而另一个工具归咎于右括号

重复或可互换的行可以产生几个相同长度的公共子序列。 ToolAcre 通过在两个相邻表值相等时优先删除来解决平局问题。另一个正确的实现可以首先选择添加,并以相同的编辑成本呈现不同外观的对齐。

这就是为什么空行或右大括号可能会附加到工具中的不同块上。这种差异并不自动意味着比较丢失了内容。在将表示差异视为相互竞争的事实主张之前,请阅读原始行号和周围未更改的行。

这不包括什么 - 语义或结构比较、移动检测和单词级突出显示超出了基于行的差异计算范围

此路径中没有任何内容解析语法树、识别重命名的标识符、标记移动的块或理解散文含义。移动的段落违反了共享顺序要求,并且可能会以删除的形式出现一次,也可能以添加的形式出现一次。该工具也不计算行内的字符或单词级突出显示。

这些省略是边界,而不是隐藏模式。使用语言感知审阅者进行语义声明和合并历史记录的版本控制。文本差异回答了两个有序行序列如何不同的狭义问题,然后让人们解释这些文本编辑是否重要。

要点:突出显示的行的真正含义 — 总结了如何将行差异读取为最短的编辑故事,以及 ToolAcre 的文本比较如何在您的选项卡中运行此内容而不上传任何内容

将绿色和红色行视为 LCS 派生的解释,而不是作为作者意图的证明。前缀和后缀修剪会改变工作量,但不会改变最终的行计数。即使大小写或空格选项提供了更宽松的匹配键,原始文本仍保留在每一行中。

比较通过导入的浏览器模块执行并使用 DOM 文本节点进行渲染;刀具路径中没有转换终点。尝试一个五行示例,交换两边,然后下载补丁形状的输出,看看方向如何在不发明语义的情况下将添加更改为删除。