2

我正在尝试在 perl 中转换以下结构(偶数元素是“父母”,奇数是“孩子”):

$VAR1 = 'ng1';
$VAR2 = [
          'ng1_1',
          'ng1_2',
          'ng1_3',
          'ng1_4'
        ];
$VAR3 = 'ng2';
$VAR4 = [
          'ng2_1',
          'ng2_2',
          'ng2_3',
          'ng2_4'
        ];
$VAR5 = 'ng3';
$VAR6 = [
          'ng3_1',
          'ng3_2',
          'ng3_3',
          'ng3_4'
        ];
$VAR7 = 'ng1_1';
$VAR8 = [
          'ng1_1_1',
          'ng1_1_2',
          'ng1_1_3',
          'ng1_1_4'
        ];
$VAR9 = 'ng1_1_1';
$VAR10 = [
           'ng1_1_1_u1',
           'ng1_1_1_u2',
           'ng1_1_1_u3'
         ];
$VAR11 = 'ng2_1';
$VAR12 = [
           'ng2_1_u1',
           'ng2_1_u2',
           'ng2_1_u3'
         ];

树结构,如下所示:

$VAR1 = 'ng1';
$VAR2 = [
          'ng1_1',
          [
            'ng1_1_1',
            [
              'ng1_1_1_u1',
              'ng1_1_1_u2',
              'ng1_1_1_u3'
            ],
            'ng1_1_2',
            'ng1_1_3',
            'ng1_1_4'
          ],
          'ng1_2',
          'ng1_3',
          'ng1_4'
        ];
$VAR3 = 'ng2';
$VAR4 = [
          'ng2_1',
          [
            'ng2_1_u1',
            'ng2_1_u2',
            'ng2_1_u3'
          ],
          'ng2_2',
          'ng2_3',
          'ng2_4'
        ];
$VAR3 = 'ng3';
$VAR4 = [
          'ng3_1',
          'ng3_2',
          'ng3_3',
          'ng3_4'
        ];

但是在“for循环”之后,我注意到@arr由于未知原因而更改为:

$VAR1 = 'ng1';
$VAR2 = [
          'ng1_1',
          [
            'ng1_1_1',
            [
              'ng1_1_1_u1',
              'ng1_1_1_u2',
              'ng1_1_1_u3'
            ],
            'ng1_1_2',
            'ng1_1_3',
            'ng1_1_4'
          ],
          'ng1_2',
          'ng1_3',
          'ng1_4'
        ];
$VAR3 = 'ng2';
$VAR4 = [
          'ng2_1',
          'ng2_2',
          'ng2_3',
          'ng2_4'
        ];
$VAR5 = 'ng3';
$VAR6 = [
          'ng3_1',
          'ng3_2',
          'ng3_3',
          'ng3_4'
        ];
$VAR7 = 'ng1_1';
$VAR8 = $VAR2->[1];
$VAR9 = 'ng1_1_1';
$VAR10 = $VAR2->[1][1];
$VAR11 = 'ng2_1';
$VAR12 = [
           'ng2_1_u1',
           'ng2_1_u2',
           'ng2_1_u3'
         ];

有人可以解释一下为什么会这样吗?我为此使用的代码如下(只有一个用于调试目的的 for 循环)。也许这不是最佳代码,欢迎任何建议。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @arr = (
        'ng1',     ['ng1_1','ng1_2', 'ng1_3', 'ng1_4'],
        'ng2',     ['ng2_1','ng2_2', 'ng2_3', 'ng2_4'],
        'ng3',     ['ng3_1','ng3_2', 'ng3_3', 'ng3_4'],
        'ng1_1',   ['ng1_1_1','ng1_1_2', 'ng1_1_3', 'ng1_1_4'],
        'ng1_1_1', ['ng1_1_1_u1', 'ng1_1_1_u2', 'ng1_1_1_u3'],
        'ng2_1',   ['ng2_1_u1', 'ng2_1_u2', 'ng2_1_u3']
);

my @tree;

#print "\nBEFORE CALLING FIRST FOR LOOP\n";
#print Dumper @arr;

$tree[0] = $arr[0];
$tree[1] = $arr[1];
for (my $i=2; $i < @arr; $i+=2){
  &buildTree(\@tree, $arr[$i], $arr[$i+1]);
}

#print "\nAFTER CALLING FIRST FOR LOOP\n";
#print Dumper @arr;

#$tree[2] = $arr[2];
#$tree[3] = $arr[3];
#for (my $i=4; $i < @arr; $i+=2){
#  &buildTree(\@tree, $arr[$i], $arr[$i+1]);
#}

sub buildTree{
  my ($tree, $parNg, $subNg) = @_;
  for my $treeElement (@{$tree}){
    if (ref $treeElement eq "ARRAY"){
      &buildTree($treeElement, $parNg, $subNg);
    }
    else{
      if ($treeElement eq $parNg){
        my ($index) = grep { $tree->[$_] eq $treeElement } 0..scalar(@$tree)-1;
        splice @{$tree}, $index + 1, 0, $subNg;
      }
    }
  }
}

谢谢

4

1 回答 1

2

哈希是树的更好结构,因为节点名称不能重复。

#!/usr/bin/perl
use warnings;
use strict;

use Data::Dumper;

my %tree = (
            ng1     => ['ng1_1'      , 'ng1_2'      , 'ng1_3'     , 'ng1_4'  ],
            ng2     => ['ng2_1'      , 'ng2_2'      , 'ng2_3'     , 'ng2_4'  ],
            ng3     => ['ng3_1'      , 'ng3_2'      , 'ng3_3'     , 'ng3_4'  ],
            ng1_1   => ['ng1_1_1'    , 'ng1_1_2'    , 'ng1_1_3'   , 'ng1_1_4'],
            ng1_1_1 => ['ng1_1_1_u1' ,  'ng1_1_1_u2', 'ng1_1_1_u3'           ],
            ng2_1   => ['ng2_1_u1'   ,  'ng2_1_u2'  , 'ng2_1_u3'             ],
           );

my $change = 1;
while ($change) {
    undef $change;

    for my $remove (keys %tree) {
        my @nonleaves = grep exists $tree{$_}, @{ $tree{$remove} };

        if (not @nonleaves) {
            my ($parent) = grep { grep $_ eq $remove, @{ $tree{$_} } } keys %tree;
            next unless $parent;

            $_ eq $remove and $_ = { $remove => $tree{$remove} } for @{ $tree{$parent} };
            delete $tree{$remove};
            $change = 1;
        }
    }
}

print Dumper \%tree;

输出:

$VAR1 = {
          'ng1' => [
                     {
                       'ng1_1' => [
                                    {
                                      'ng1_1_1' => [
                                                     'ng1_1_1_u1',
                                                     'ng1_1_1_u2',
                                                     'ng1_1_1_u3'
                                                   ]
                                    },
                                    'ng1_1_2',
                                    'ng1_1_3',
                                    'ng1_1_4'
                                  ]
                     },
                     'ng1_2',
                     'ng1_3',
                     'ng1_4'
                   ],
          'ng3' => [
                     'ng3_1',
                     'ng3_2',
                     'ng3_3',
                     'ng3_4'
                   ],
          'ng2' => [
                     {
                       'ng2_1' => [
                                    'ng2_1_u1',
                                    'ng2_1_u2',
                                    'ng2_1_u3'
                                  ]
                     },
                     'ng2_2',
                     'ng2_3',
                     'ng2_4'
                   ]
        };
于 2013-05-30T12:57:05.223 回答