【发布时间】:2019-05-17 00:56:09
【问题描述】:
假设我们有一堆看起来像这样的子树:
subtree1 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": []
},
{
"id": "edit",
"caption": "Edit",
"children": []
},
{
"id": "tools",
"caption": "Tools",
"children": [
{
"id": "packages",
"caption": "Packages",
"children": []
}
]
},
{
"id": "help",
"caption": "Help",
"children": []
},
]
}
subtree2 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": [
{"caption": "New"},
{"caption": "Exit"},
]
}
]
}
subtree3 = {
"id": "root",
"children": [
{
"id": "edit",
"children": [
{"caption": "Copy"},
{"caption": "Cut"},
{"caption": "Paste"},
]
},
{
"id": "help",
"children": [
{"caption": "About"},
]
}
]
}
subtree4 = {
"id": "root",
"children": [
{
"id": "edit",
"children": [
{
"id": "text",
"caption": "Text",
"children": [
{ "caption": "Insert line before" },
{ "caption": "Insert line after" }
]
}
]
}
]
}
我试图弄清楚如何编写 merge 函数,例如执行以下操作:
tree0 = merge(subtree1, subtree2)
tree0 = merge(tree0, subtree3)
tree0 = merge(tree0, subtree4)
将产生:
tree0 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": [
{"caption": "New"},
{"caption": "Exit"},
]
},
{
"id": "edit",
"caption": "Edit",
"children": [
{"caption": "Copy"},
{"caption": "Cut"},
{"caption": "Paste"},
{
"id": "text",
"caption": "Text",
"children": [
{ "caption": "Insert line before" },
{ "caption": "Insert line after" }
]
}
]
},
{
"id": "tools",
"caption": "Tools",
"children": [
{
"id": "packages",
"caption": "Packages",
"children": []
}
]
},
{
"id": "help",
"caption": "Help",
"children": [
{"caption": "About"},
]
},
]
}
但是做这样的事情:
tree1 = merge(subtree1, subtree2)
tree1 = merge(tree1, subtree4)
tree1 = merge(tree1, subtree3)
会产生:
tree1 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": [
{"caption": "New"},
{"caption": "Exit"},
]
},
{
"id": "edit",
"caption": "Edit",
"children": [
{
"id": "text",
"caption": "Text",
"children": [
{ "caption": "Insert line before" },
{ "caption": "Insert line after" }
]
},
{"caption": "Copy"},
{"caption": "Cut"},
{"caption": "Paste"},
]
},
{
"id": "tools",
"caption": "Tools",
"children": [
{
"id": "packages",
"caption": "Packages",
"children": []
}
]
},
{
"id": "help",
"caption": "Help",
"children": [
{"caption": "About"},
]
},
]
}
否则,以相同的顺序加载子树将始终生成相同的树,但是如果您以不同的顺序使用相同的子树列表,则不能保证生成相同的树(因为子列表可以以不同的方式扩展顺序)。
我已经尝试对此进行编码,但我不知道merge 算法的行为如何,这是我的问题。谁能提供代码/伪代码/解释以便我实现它?
PS:下面你会发现一些我认为可以让我取得胜利的随机尝试
if __name__ == '__main__':
from collections import defaultdict
subtree1 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": []
},
{
"id": "edit",
"caption": "Edit",
"children": []
},
{
"id": "tools",
"caption": "Tools",
"children": [
{
"id": "packages",
"caption": "Packages",
"children": []
}
]
},
{
"id": "help",
"caption": "Help",
"children": []
},
]
}
subtree2 = {
"id": "root",
"children": [
{
"id": "file",
"caption": "File",
"children": [
{"caption": "New"},
{"caption": "Exit"},
]
}
]
}
subtree3 = {
"id": "root",
"children": [
{
"id": "edit",
"children": [
{"caption": "Copy"},
{"caption": "Cut"},
{"caption": "Paste"},
]
},
{
"id": "help",
"children": [
{"caption": "About"},
]
}
]
}
subtree4 = {
"id": "root",
"children": [
{
"id": "edit",
"children": [
{
"id": "text",
"caption": "Text",
"children": [
{"caption": "Insert line before"},
{"caption": "Insert line after"}
]
}
]
}
]
}
lst = [
subtree1,
subtree2,
subtree3,
subtree4
]
def traverse(node, path=[]):
yield node, tuple(path)
for c in node.get("children", []):
path.append(c.get("id", None))
yield from traverse(c)
path.pop()
# Levels & Hooks
dct_levels = defaultdict(list)
dct_hooks = defaultdict(list)
for subtree in lst:
for n, p in traverse(subtree):
if p not in dct_levels[len(p)]:
dct_levels[len(p)].append(p)
dct_hooks[p].append(n)
print(dct_levels)
print(dct_hooks[("file",)])
# Merge should happen here
tree = {
"id": "root",
"children": []
}
for level in range(1, max(dct_levels.keys()) + 1):
print("populating level", level, dct_levels[level])
但不确定我是否在这里创建了正确的结构/助手,因为目前还不清楚整个算法是如何工作的......这就是这个问题的全部内容
【问题讨论】: