/ / Podczas próby napisania skryptu do permutacji wartości na liście, otrzymuję ostrzeżenie o niezainicjowanej wartości - perl, permutacja, inicjalizacja

Próbując napisać skrypt do permutacji wartości na liście, otrzymuję ostrzeżenie o niezainicjalizowanej wartości - perl, permutacja, inicjalizacja

Jestem bardzo pewien, co się dzieje, dla różnych długości @depths, kod na ogół działa. Jednak w całym procesie produkcji, w określonych punktach, program blokuje skargi na użycie niezainicjowanej wartości.

Błędy obwiniają wiersz 20: print $chars[$depths[$y]];

Przepraszam z wyprzedzeniem, jeśli to coś oczywistego, ale zdecydowanie brakuje mi tego problemu. Przez około godzinę jeździłem w Google'u bez powodzenia, więc byłyby jakieś ruchy w dobrym kierunku bardzo docenione!

Pełny kod:

#! /usr/bin/perl -w

use strict;
use warnings;

#my @chars  = ("0" .. "9");
#my @depths = (0) x 4;
my @chars   = ("0" .. "1");
my @depths  = (0) x 3;

my ($i, $x, $y);

for ($i = 0; $i < @chars ** @depths; $i++) {

for ($y = 0; $y < @depths; $y++) {

print $chars[$depths[$y]];
}
print"n";

$depths[$#depths]++;
for($x = 0; $x < @depths; $x++) {

if($depths[$x] == @chars) {

$depths[$x-1]++;
while($x < @depths) {

$depths[$x++] = 0;
}
}
}
}

Wydajność:

000
001
010
011
Use of uninitialized value in print at a.pl line 15.
00
100
101
110

Odpowiedzi:

1 dla odpowiedzi № 1

Dodałem kilka instrukcji drukowania do kodu, a problem staje się widoczny.

#! /usr/bin/perl -w

use strict;
use warnings;

my @chars = ("0".."1");
my @depths = (0) x 3;

my $i;
my $x;
my $y;
for ($i = 0; $i < @chars**@depths; $i++)
{
printf "m = %dn", scalar(@depths);
for ($y = 0; $y < @depths; $y++)
{
print "y:$y; d[y] = $depths[$y]n";
print " :$chars[$depths[$y]]:n";
}
print"n";

printf "b[%d] ", $depths[$#depths];
$depths[$#depths]++;
printf "a[%d]n", $depths[$#depths];
for($x = 0; $x < @depths; $x++){
if($depths[$x] == @chars){
$depths[$x-1]++;
while($x < @depths){
$depths[$x++] = 0;
}
}
}
}

Dane wyjściowe:

m = 3
y:0; d[y] = 0
:0:
y:1; d[y] = 0
:0:
y:2; d[y] = 0
:0:

b[0] a[1]
m = 3
y:0; d[y] = 0
:0:
y:1; d[y] = 0
:0:
y:2; d[y] = 1
:1:

b[1] a[2]
m = 3
y:0; d[y] = 0
:0:
y:1; d[y] = 1
:1:
y:2; d[y] = 0
:0:

b[0] a[1]
m = 3
y:0; d[y] = 0
:0:
y:1; d[y] = 1
:1:
y:2; d[y] = 1
:1:

b[1] a[2]
m = 3
y:0; d[y] = 0
:0:
y:1; d[y] = 2
Use of uninitialized value within @chars in concatenation (.) or string at perm.pl line 18.
::
y:2; d[y] = 0
:0:

b[0] a[1]
m = 3
y:0; d[y] = 1
:1:
y:1; d[y] = 0
:0:
y:2; d[y] = 0
:0:

b[0] a[1]
m = 3
y:0; d[y] = 1
:1:
y:1; d[y] = 0
:0:
y:2; d[y] = 1
:1:

b[1] a[2]
m = 3
y:0; d[y] = 1
:1:
y:1; d[y] = 1
:1:
y:2; d[y] = 0
:0:

b[0] a[1]

Linia bezpośrednio przed raportem o błędzie pokazuje to $depths[$y] jest 2, ale tablica @chars zawiera tylko elementy z indeksami 0 i 1, więc ostrzeżenie jest prawidłowe.


1 dla odpowiedzi nr 2

Myśleć o @depths jako podstawowa liczba N (gdzie N jest liczbą @chars) i każdy element @depths jest cyfrą. Próbujesz dodać jeden do tego numeru, ale nie udało ci się.

Nośnik propaguje od najmniej znaczącegocyfra na najbardziej znaczącą, więc powinieneś być w pętli niż obsługuje pętlę carry od najmniej znaczącej cyfry do najważniejszej, ale robisz to w odwrotnej kolejności. $x powinien zaczynać się od $#depth i zmniejsza się w miarę postępu pętli.

Spójrzmy na przykład. Powiedzmy, że jest 10 symboli (@chars == 10):

 456999   <- @depth
+     1
-------
457000

Więc chcesz zwiększyć cyfrę, która nie jest równa $#charsi ustawione na zero wszystkie prawe cyfry, które są równe $#chars. Oto jak to zakodowałem:

#!/usr/bin/perl -w

use strict;
use warnings;

my @chars = ("0".."2");
my @depths = (0) x 3;

OUTER: while (1) {
print @chars[@depths], "n";

my $x = $#depths;
while ($depths[$x] == $#chars) {
$depths[$x] = 0;
last OUTER if $x == 0;
--$x;
}

++$depths[$x];
}