代码之家  ›  专栏  ›  技术社区  ›  monkut

设置合并以合并和展平树结构

  •  3
  • monkut  · 技术社区  · 12 年前

    我有一组这样的数据:

    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]]
    

    固定尝试 ,似乎有效,有没有更有效的方法?

    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)
    

    是否有有效的方法将数据合并到 预期产量 ?

    2 回复  |  直到 12 年前
        1
  •  3
  •   Hyperboreus    12 年前

    我不知道这是否有效,但它似乎有效:

    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
  •  1
  •   g.d.d.c    12 年前

    我想到了这个,它与上面的类似,但不完全相同。我的破坏性很强,它消耗了输入数据结构,我认为它在同一点有界(在没有任何输入数据相关的情况下为^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