【问题标题】:How to correctly diff trees (that is, nested lists of strings)?如何正确区分树(即嵌套的字符串列表)?
【发布时间】:2013-10-15 20:49:11
【问题描述】:

我正在在线编辑器中处理由嵌套的字符串列表组成的数据类型。请注意,如果我要在每次更改单个值时传输整个结构,流量可能会变得难以忍受。所以,为了减少流量,我考虑过应用差异工具。问题是:如何找到并报告两棵树的差异?例如:

["ah","bh",["ha","he",["li","no","pz"],"ka",["kat","xe"]],"po","xi"] ->
["ah","bh",["ha","he",["li","no","pz"],"ka",["rag","xe"]],"po","xi"]

在那里,唯一的变化是树深处的"kat" -> "rag"。大多数 diff 工具都适用于平面列表、文件等,但不适用于树。我找不到有关该特定问题的任何文献。报告这种变化的最小方法是什么,找到它的有效算法是什么?

【问题讨论】:

  • 您在寻找 XSLT 吗?
  • 嗯,对不起?我不知道 XSLT 是什么意思,但如果它是关于 XML 的,那么就没有... 编辑:阅读它看起来很有趣的描述,也许是用于 JSON 的 XSLT?我现在就研究一下。
  • 考虑在cs.stackexchange.com上问这些类型的问题。

标签: algorithm data-structures language-agnostic diff


【解决方案1】:

XML 是一种常用的树状数据结构,常用于描述需要监控随时间变化的结构化文档或其他分层对象。因此,最近关于树差异的大部分工作都是在 XML 的上下文中进行的,这一点也就不足为奇了。

这是 2006 年的一项调查,其中包含许多可能有用的链接:Change Detection in XML Trees

上面的一个更有趣的链接,伴随着一个名为 TreePatch 的开源实现,但现在似乎已经失效:Kyriakos Komvoteas' thesis

Daniel Ehrenberg 撰写的另一篇调查文章,其中包含更多参考资料。 (那个来自http://cstheory.stackexchange.com上的question

祝你好运。

【讨论】:

    【解决方案2】:

    查找两棵树之间的差异看起来有点像在树中搜索。您知道的唯一区别是您必须深入了解它们。 您可以同时搜索两棵树,当您发现差异时,将一棵更改为另一棵(如果这是您的目标 - 最终得到相同的树,而不是每次都发送一棵)。

    我在区分 2 棵树时发现的一些链接:

    How can i diff two trees to determine parental changes?

    Detect differences between tree structures

    Diff algorithms

    希望这些链接对您有用。 :)

    【讨论】:

      【解决方案3】:
      1. 您可以使用任何通用的 DIFF 算法,找到现成的库不是问题。
      2. 如果您可以使用 ZLIB 库,我可以建议另一种解决方案。通过一些技巧,可以使用这个库在两个任意二进制文件之间发送非常压缩的差异,我们称它们为 A 和 B(以及差异 Bc)。

      第一面:

      1. 初始化 ZLIB 流
      2. 使用 Z_SNC_FLUSH 压缩 A->Ac(我们不需要结果,因此可以释放 Ac)
      3. 使用 Z_SNC_FLUSH 压缩 B->Bc
      4. 取消初始化 ZLIB 流

      我们首先使用特殊标志压缩块 A,强制 ZLib 处理和输出所有数据。但它不会重置压缩状态!当我们压缩块 B 时,压缩器已经知道 A 的子序列,并且会非常有效地压缩块 B(如果它们有很多共同点)。 Bc 是唯一要发送的数据。

      第二面:

      1. 初始化 ZLIB 流
      2. 使用 Z_SNC_FLUSH 压缩 A->Ac
      3. 取消初始化 ZLIB 流

      我们需要解压缩与压缩完全相同的块。这就是我们需要交流电的原因。

      1. 再次初始化 ZLIB 流
      2. 使用 Z_SNC_FLUSH 解压缩 Ac->A
      3. 使用 Z_SNC_FLUSH 解压缩 Bc->B
      4. 取消初始化 ZLIB 流

      现在我们可以解压Ac-A(我们必须解压,因为我们是在另一边解压的,它有助于解压器学习块A的所有子序列),最后是Bc->B。

      ZLib 的用法有点不寻常和棘手,但在这种情况下,Bc 不仅仅是压缩块 B,它实际上是压缩块 A 和 B 之间的差异。如果 ZLIB 字典的大小与块 A 的大小。对于巨大的数据块,它不会那么有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-08
        • 2017-07-08
        • 2023-03-30
        • 2015-05-14
        • 2014-04-26
        • 2013-05-08
        • 2017-02-26
        • 1970-01-01
        相关资源
        最近更新 更多