как создать структуру данных, как дерево - PullRequest
0 голосов
/ 09 мая 2018

для моего проекта мне нужно построить древовидную структуру. Я ищу способ вырастить это на листьях. Я упростила свою неудачную попытку, используя списочную структуру:

my $root = a => (b => (c=> Nil));
my $here := $root;
while $here.value ~~ Pair {
  $here := $here.value;
}
$here = d => Nil;

, который не работает, потому что я, конечно, не могу изменить ноль. Невозможно присвоить неизменное значение Как я могу сделать эту работу?

Спасибо, Тео ван ден Хеувел

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Вы используете привязка , а не присвоение для $here

my $root = a => (b => (c=> Nil));
my $here = $root;
while $here.value ~~ Pair {
  $here = $here.value;
}
$here = d => Nil;

Когда вы используете связывание, левая и правая стороны являются одним и тем же объектом.И как только они становятся одним и тем же объектом, они не могут измениться (если связанный объект является неизменным).Они неизменны:

my $bound := 3; $bound = 'þorn'; say $bound; 
# OUTPUT: «Cannot assign to an immutable value␤» 

3 выше является неизменным, поэтому вы не можете назначить его.В коде, который вы предоставили, вы можете изменить значение путем повторного связывания, пока не получите неизменное значение, последнее Pair, которое объясняет сообщение.

Просто используйте обычное присваивание, и вы готовы идти,Если вы хотите где-то сохранить исходное значение $root, просто сделайте это и используйте $root для навигации по дереву

my $root = a => (b => (c=> Nil));
my $here = $root;
while $root.value ~~ Pair {
  $root = $root.value;
}
$here = d => Nil;
say $here;
say $root; 

$here будет по-прежнему равен исходному корню,и $root перейдет к последней ветке и листу.

0 голосов
/ 10 мая 2018

На основе ценного вклада @Elizabeth, @ Håkon и @jjmerelo я создал реализацию дерева примеров.

my @paths = <<aap-noot-mies aap-noot-hut aap-juf tuin>>;

my %root;
for @paths -> $fn {
  my @path = $fn.split: '-';
  add-to-tree(@path);
}

print_tree(0, %root);

sub add-to-tree(@path) {
  my %tmp := %root;
  for @path -> $step {
    unless %tmp{$step}:exists {
      my %newtmp;
      %tmp{$step} = %newtmp;
    }
    %tmp := %tmp{$step};
  }
}

sub print_tree($ind, %from) {
  my $margin = ' ' x $ind;
  if %from {
    for %from.kv -> $k, $v {
      say "$margin$k:";
      print_tree($ind + 1, %$v);
    }
  } else {
    say "$margin.";
  }
}
0 голосов
/ 09 мая 2018

Я думаю, что сообщение об ошибке, которое вы получаете "Невозможно присвоить неизменное значение" , связано с тем, что значение не является контейнером .Вот пример, где я делаю конечный узел контейнером:

my $root = a => (b => (my $ = (c => Nil)));
my $here := $root;
while $here.value ~~ Pair {
  $here := $here.value;
}
$here = d => Nil;

Теперь нет сообщения об ошибке.

...