/ / Beim Versuch, ein Skript zu schreiben, um Werte in einer Liste zu permutieren, erhalte ich eine nicht initialisierte Wertwarnung - Perl, Permutation, Initialisierung

Beim Versuch, ein Skript zu schreiben, um Werte in einer Liste zu permutieren, erhalte ich eine nicht initialisierte Wertwarnung - Perl, Permutation, Initialisierung

Ich bin sehr unsicher, was passiert. Für verschiedene Längen von @depthsfunktioniert der Code im Allgemeinen. In der gesamten Ausgabe werden jedoch an bestimmten Stellen Beschwerden über die Verwendung eines nicht initialisierten Wertes angezeigt.

Die Fehler Schuld 20: print $chars[$depths[$y]];

Ich entschuldige mich im Voraus, wenn es etwas offensichtlich ist, aber ich vermisse definitiv das Problem. Ich habe ungefähr eine Stunde lang gegoogelt, ohne Glück, also wäre jeder Ansturm in die richtige Richtung sehr geschätzt!

Vollständiger Code:

#! /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;
}
}
}
}

Ausgabe:

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

Antworten:

1 für die Antwort № 1

Ich habe Ihrem Code einige Druckanweisungen hinzugefügt, und das Problem wird offensichtlich.

#! /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;
}
}
}
}

Die Ausgabe war:

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]

Die Zeile unmittelbar vor dem Fehlerbericht zeigt das an $depths[$y] ist 2, aber das Array @chars enthält nur Elemente mit den Indizes 0 und 1, daher ist die Warnung korrekt.


1 für die Antwort № 2

Denk an @depths als eine Basis N Nummer (wobei N die Anzahl von ist @chars), und jedes Element von @depths ist eine Ziffer. Sie versuchen, einen zu dieser Nummer hinzuzufügen, aber Sie scheitern.

Ein Übertrag breitet sich von dem am wenigsten signifikanten ausZiffer zu den wichtigsten, so sollten Sie die Schleife sein als behandelt die Carry sollte Schleife von der niedrigstwertigen Stelle zu den wichtigsten, aber Sie tun es in der umgekehrten Reihenfolge. $x sollte bei beginnen $#depth und verringern, wenn die Schleife fortschreitet.

Schauen wir uns ein Beispiel an. Sagen wir, es gibt 10 Symbole (@chars == 10):

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

Sie möchten also die rechte Ziffer erhöhen, die nicht gleich ist $#chars, und setzen Sie alle rechten Stellen, die gleich sind, auf Null $#chars. Hier habe ich das so codiert:

#!/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];
}