如何正确区分树(即嵌套的字符串列表)?

时间:2013-10-08 18:58:56

标签: algorithm data-structures language-agnostic diff

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

["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工具都适用于平面列表,文件等,但不适用于树。我找不到关于这个具体问题的任何文献。报告此类更改的最小方法是什么,找到它的有效算法是什么?

3 个答案:

答案 0 :(得分:2)

XML是一种常用的树状数据结构,通常用于描述需要监视其随时间变化的结构化文档或其他分层对象。因此,最近在树差异方面的大部分工作都是在XML环境中应该不足为奇。

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

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

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

祝你好运。

答案 1 :(得分:2)

找到两棵树之间的区别看起来有点像在树上搜索。你知道的唯一区别就是必须达到两者的底部。 你可以同时搜索两棵树,当你遇到差异时,将一个树换到另一个树(如果这是你的目标 - 最终得到相同的树,而不是每次都发送一个树)。

我在发现2棵树时发现了一些链接:

How can i diff two trees to determine parental changes?

Detect differences between tree structures

Diff algorithms

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

答案 2 :(得分:2)

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

    1. Init ZLIB stream
    2. 使用Z_SNC_FLUSH压缩A-> Ac(我们不需要结果,因此可以释放Ac)
    3. 使用Z_SNC_FLUSH
    4. 压缩B-> Bc
    5. Deinit ZLIB stream
    6. 我们首先用特殊标志压缩块A,强制ZLib处理并输出所有数据。但它不会重置压缩状态!当我们压缩块B时,压缩器已经知道A的子序列并且将非常有效地压缩块B(如果它们有很多共同点)。 Bc是唯一要发送的数据。

      第2面:

      1. Init ZLIB stream
      2. 使用Z_SNC_FLUSH
      3. 压缩A-> Ac
      4. Deinit ZLIB stream
      5. 我们需要解压缩与压缩完全相同的块。这就是为什么我们需要Ac。

        1. 再次启动ZLIB流
        2. DeCompress Ac-> A with Z_SNC_FLUSH
        3. 使用Z_SNC_FLUSH
        4. 解压缩Bc-> B
        5. Deinit ZLIB stream
        6. 现在我们可以解压缩Ac-A(我们必须,因为我们在另一方面做了,它有助于解压缩器学习块A的所有子序列),最后Bc-> B。

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