如果人们发现此问题并需要为Node.js或浏览器实现某些功能,我将为我编写的实现提供一个链接和代码示例,您可以在github上找到:(https://github.com /hoonto/jqgram.git)基于现有的PyGram Python代码(https://github.com/Sycondaman/PyGram)。
这是一个树形编辑距离近似算法,但是它比试图找到真实的编辑距离快得多。逼近在O(n log n)时间和O(n)空间中执行,而使用已知的真实编辑距离算法,真实编辑距离通常为O(n ^ 3)或O(n ^ 2)。请参阅PQ-Gram算法来自的学术论文:(http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf)
因此,使用jqgram:
例:
var jq = require("jqgram").jqgram;
var root1 = {
"thelabel": "a",
"thekids": [
{ "thelabel": "b",
"thekids": [
{ "thelabel": "c" },
{ "thelabel": "d" }
]},
{ "thelabel": "e" },
{ "thelabel": "f" }
]
}
var root2 = {
"name": "a",
"kiddos": [
{ "name": "b",
"kiddos": [
{ "name": "c" },
{ "name": "d" },
{ "name": "y" }
]},
{ "name": "e" },
{ "name": "x" }
]
}
jq.distance({
root: root1,
lfn: function(node){ return node.thelabel; },
cfn: function(node){ return node.thekids; }
},{
root: root2,
lfn: function(node){ return node.name; },
cfn: function(node){ return node.kiddos; }
},{ p:2, q:3 },
function(result) {
console.log(result.distance);
});
这样一来,您可以得到一个介于0和1之间的数字。该数字越接近零,则它们与jqgram的关系就越紧密。一种方法可能是使用jqgram从给定速度的众多树中缩小几个紧密相关的树,然后对剩余的几棵树使用真正的编辑距离,您需要仔细检查这些树,为此您可以找到python例如,Zhang&Shasha算法的参考或端口实现。
请注意,lfn和cfn参数指定每个树如何独立确定每个树根的节点标签名称和子数组,以便您可以做一些时髦的事情,例如将对象与浏览器DOM进行比较。您需要做的就是提供这些函数以及每个根,而jqgram将完成其余的工作,调用lfn和cfn提供的函数来构建树。因此从某种意义上说(无论如何,我认为它)比PyGram更容易使用。另外,它的Javascript,因此请在客户端或服务器端使用它!
另外,要回答关于周期检测的问题,请检查jqgram内部的clone方法,那里有周期检测,但是值得感谢的是node-clone的作者,对该节点进行了稍微修改并包含了它。
MOVE(A,B)
似乎是一样的INSERT(A,B)
,如果A
没有任何孩子。A
如果一个人的孩子INSERT(A,B)
怎么办?(将其附加到其A
父母