为合并和展平树结构设置合并
Posted
技术标签:
【中文标题】为合并和展平树结构设置合并【英文标题】:set consolidation for merging and flattening a tree structure 【发布时间】:2013-02-20 03:11:37 【问题描述】:我有一组这样的数据:
data = 1: "root": [2],
"leaf": [10, 11, 12],
,
2: "root": [1,3],
"leaf": [13, 14, 15],
,
3: "root": [2],
"leaf": [16, 17],
,
4: "root": [],
"leaf": [17, 18, 19],
,
5: "root": [],
"leaf": [20, 21]
,
从这个数据中,初始键是一个根节点索引,它包含一个解释哪些根节点和叶节点与其相关的字典。
我想将所有索引合并到相关列表中。
由根索引连接的根索引,两个/所有根索引和所有叶索引都合并到结果列表中。 一个根索引可以通过叶子连接到另一个根,根索引和所有叶子索引都合并到结果列表中。我在找出遍历和合并数据的最佳方式时遇到了一些麻烦。从上述数据集中,预期输出为:
[[1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [5, 20, 21]]
Fixed Attempt,好像有效,有没有更有效的方法?
class MergeMachine(object):
processed = []
def merge(self, idx, parent_indexes, existing):
if idx not in self.processed:
parent_indexes.append(idx)
if self.data[idx]["root"]:
for related_root_idx in self.data[idx]["root"]:
if related_root_idx not in self.processed and related_root_idx not in parent_indexes:
existing.extend(self.merge(related_root_idx, parent_indexes, existing))
self.processed.append(related_root_idx)
existing.append(idx)
existing.extend(self.data[idx]["leaf"])
self.processed.append(idx)
return existing
def process(self, data):
results = []
self.data = data
for root_idx in self.data.keys():
r = set(self.merge(root_idx, [], []))
if r:
combined = False
for result_set in results:
if not r.isdisjoint(result_set):
result_set.union(r)
combined = True
if not combined:
results.append(r)
return results
mm = MergeMachine()
mm.process(data)
有没有一种有效的方法将数据合并到预期的输出?
【问题讨论】:
为什么 4 和它的孩子在第一个列表中? 我猜是因为它通过叶子 17 连接到根 3。 是的,这就是我试图表达的意思,“一个根索引可能通过叶子连接到另一个根”。 想一想,如果每个节点都被展平,然后不相交的检查运行,结果可以一次连接而不递归? 您应该搜索的短语是“设置合并”,例如here. 【参考方案1】:我不知道这是否有效,但它似乎有效:
data = #your data as posted
data = [set ( [k] ) | set (v ['root'] ) | set (v ['leaf'] ) for k, v in data.items () ]
merged = []
while data:
e0 = data [0]
for idx, e in enumerate (data [1:] ):
if e0 & e:
data [idx + 1] = e | e0 #idx is off by 1 as I enumerate data [1:]
break
else: merged.append (e0)
data = data [1:]
print (merged)
我猜在最坏的情况下(即不可能合并)成本应该是 O(n**2)。而且是串行的,没有递归。
【讨论】:
【参考方案2】:我想出了这个,它与上面的类似,但并不完全相同。我的是破坏性的,它消耗输入数据结构,我认为它在同一点有界(如果没有任何输入数据相关,则为 On^2)。
def merge(data):
result = []
while data:
k, v = data.popitem()
temp = set([k]) | set(v['root']) | set(v['leaf'])
for idx, test in enumerate(result):
if test & temp:
result[idx] |= temp
break
else:
result.append(temp)
return result
【讨论】:
以上是关于为合并和展平树结构设置合并的主要内容,如果未能解决你的问题,请参考以下文章