Когда вы читаете ввод, используя <>
, он включает в себя завершающий символ новой строки. В результате он не равен ни одной из клавиш в %graph
(которые, вероятно, не имеют символов новой строки). Быстрое исправление - chomp
root.
...
my $root = <>;
chomp $root;
Полное исправление состоит в том, чтобы проверить, является ли $root
допустимой вершиной, и вывести ошибку, если нет. Обратите внимание, что вы не должны обрабатывать пользовательский ввод и логику приложения в одной и той же функции. Отдельные проблемы для уменьшения сцепления .
Также, глобалы плохие . Переменные пакета не так уж плохи, если вы это делаете, но %group
следует передать в dijkstra
(как ссылка ), чтобы реализация не была так тесно связана с графиком. Передача графика в качестве параметра приводит к ужесточению кода.
Обратите внимание, что вам не нужно определять свою собственную бесконечность. Perl имеет inf
(и -inf
).
sub dijkstra {
my ($graph, $root) = @_;
my (%dist, %prev);
############################ the algorithm ####
# first, set all distances to infinity
foreach $n (keys %{$graph}) { $dist{$n} = inf; $prev{$n}=$n; }
# .. except the source
$dist{$root} = 0;
# loop while we have unsolved nodes
# sort unsolved by distance from root
foreach my $n1 (sort keys %{$graph}) {
foreach my $n2 (keys %{$graph->{$n1}}) {
if (($dist{$n2} eq inf) ||
($dist{$n2} > ($dist{$n1} + $graph->{$n1}{$n2}) )) {
$dist{$n2} = $dist{$n} + $graph->{$n1}{$n2};
$prev{$n2} = $n1;
}
}
}
return (\%prev, \%dist);
}
sub getNode {
my $graph = shift;
print "Enter a node\n";
my $root= <>;
chomp $root;
if (! exists $graph->{$root}) {
die("'$root' isn't a valid node.\n");
}
return $root;
}
sub printPaths {
my ($graph, $prev, $dist) = @_;
my $path;
foreach $n (keys %{$graph}) {
my $t = $n;
$path = $t;
while ($t ne $root) {
$t = $prev->{$t}; $path = "$t -> " . $path;
}
print "$n\t$dist->{$n}\t$path\n";
}
}
$graph = {
'A' => {'B' => 1, 'C' => 5},
'B' => {'C' => 4, 'D' => 2},
'C' => {'A' => 1, 'B' => 3},
'D' => {'C' => 2, 'B' => 3}
};
$root = getNode($graph);
#($prev, $dist) = dijkstra(\%graph, $root);
#printPaths($graph, $prev, $dist);
# or, for obfuscation:
printPaths($graph, dijkstra($graph, $root));
Чтобы отладить что-то подобное, вы можете использовать скаффолдинг (для этого выведите сообщения об отладке в различных точках кода; Data :: Dumper полезен для этого). А еще лучше научитесь использовать интерактивный отладчик .