如何从多个列表生成父子元素的有序列表,具有多个根?

时间:2012-05-03 14:57:03

标签: perl list parent-child

我最近在这里问了一个问题,得到了一些非常优雅的答案。这是:

访问How to generate an ordered list of parent-child elements from multiple lists?

我有一个类似的问题,其中可能有多个根,这意味着有单独的树。这是一个例子(在perl中);

my @rules = (
  [ qw( A B C ) ],
  [ qw( B D E ) ],
  [ qw( C H G ) ],
  [ qw( G H   ) ],
  [ qw( Z C   ) ]
);

在列表@rules中,A是B和C的父级。通常,第一个元素是列表中其余元素的父元素。

我想处理这组数组,并生成一个包含正确顺序的列表。在这里,A和Z必须先于其他元素(A和Z的顺序并不重要,因为它们是独立的)。以下是两个示例解决方案:

(A,Z,B,C,D,E,F,G,H), or (Z,A,B,D,E,F,C,G,H)

重要提示:查看数组3; H出现在G之前,即使它是第四阵列中G的孩子。因此,每个数组中没有特定的子项顺序,但是在最终结果中(如上所示)必须在其子/ ren之前具有任何父项。

Here, A, and H are independent of each other, but use common nodes.

1 个答案:

答案 0 :(得分:1)

这个怎么样?不过,这很简单。

my @rules = (
  [ qw( A B C ) ],
  [ qw( B D E F ) ],
  [ qw( C H G ) ],
  [ qw( G H   ) ],
  [ qw( Z C   ) ]
);

my %weight_for;
for (@rules) {
  my ($parent, @children) = @{$_};
  $weight_for{$_}++ for ($parent, @children);
  $weight_for{$_} += $weight_for{$parent} 
    for @children; 
}

print "$_ = $weight_for{$_}\n" 
  for sort { $weight_for{$a} <=> $weight_for{$b} } keys %weight_for;