GoGPT Best VPN GoSearch

OnWorks-favicon

perllol - Online in de cloud

Voer Perllol uit in de gratis hostingprovider OnWorks via Ubuntu Online, Fedora Online, Windows online emulator of MAC OS online emulator

Dit is de opdracht perllol die kan worden uitgevoerd in de gratis hostingprovider OnWorks met behulp van een van onze verschillende gratis online werkstations, zoals Ubuntu Online, Fedora Online, Windows online emulator of MAC OS online emulator

PROGRAMMA:

NAAM


perllol - Arrays van arrays manipuleren in Perl

PRODUCTBESCHRIJVING


Verklaring en Toegang of arrays of arrays
De eenvoudigste twee-niveau datastructuur om in Perl te bouwen is een array van arrays, soms
wordt ook wel een lijst van lijsten genoemd. Het is redelijk gemakkelijk te begrijpen, en bijna
alles wat hier van toepassing is, zal later ook van toepassing zijn met de mooiere gegevens
structuren.

Een array van een array is gewoon een gewone oude array @AoA die je met twee kunt benaderen
subscripts, zoals $AoA[3][2]. Hier is een declaratie van de array:

gebruik 5.010; # zodat we say() kunnen gebruiken

# wijs aan onze array een array met array-referenties toe
@AoA = (
[ "fred", "barney", "kiezels", "bambam", "dino", ],
[ "george", "jane", "elroy", "judy", ],
[ "homer", "bart", "marge", "maggie", ],
);
zeg $AoA[2][1];
bart

Nu moet je er heel voorzichtig mee zijn dat het buitenste beugeltype rond is, dat wil zeggen een
haakjes. Dat komt omdat je toewijst aan een @array, dus je hebt haakjes nodig. Als
je wilde daar niet om een ​​@AoA te zijn, maar eerder een verwijzing ernaar, zou je kunnen doen
zoiets als dit:

# wijs een referentie toe aan een array met array-referenties
$ref_naar_AoA = [
[ "fred", "barney", "kiezels", "bambam", "dino", ],
[ "george", "jane", "elroy", "judy", ],
[ "homer", "bart", "marge", "maggie", ],
];
zeg $ref_to_AoA->[2][1];
bart

Merk op dat het type van de buitenste haakjes is gewijzigd en dat onze toegangssyntaxis dus ook is gewijzigd.
Dat komt omdat je in Perl, in tegenstelling tot C, niet vrijelijk arrays en referenties kunt uitwisselen
daartoe. $ref_to_AoA is een verwijzing naar een array, terwijl @AoA een echte array is.
Op dezelfde manier is $AoA[2] geen array, maar een array-ref. Hoe kun je dit dan schrijven:

$AoA[2][2]
$ref_to_AoA->[2][2]

in plaats van dat ik deze moet schrijven:

$AoA[2]->[2]
$ref_to_AoA->[2]->[2]

Dat komt omdat de regel is dat alleen bij aangrenzende haakjes (of ze nu vierkant of gekruld zijn),
U kunt de pointer-dereferentiepijl weglaten. Maar u kunt dit niet doen voor de zeer
de eerste als het een scalair is die een referentie bevat, wat betekent dat $ref_to_AoA altijd
heeft het nodig.

Groeiend Uw Eigen
Dat is allemaal leuk en aardig voor de declaratie van een vaste datastructuur, maar wat als je
om gaandeweg nieuwe elementen toe te voegen, of om het geheel vanaf nul op te bouwen?

Laten we eerst eens kijken hoe we het uit een bestand kunnen lezen. Dit is zoiets als het toevoegen van een rij aan een
tijd. We gaan ervan uit dat er een plat bestand is waarin elke regel een rij is en elk woord een
element. Als je een @AoA-array probeert te ontwikkelen die al deze elementen bevat, is dit de juiste
manier om dat te doen:

terwijl (<>) {
@tmp = gesplitst;
duw @AoA, [ @tmp ];
}

Je hebt dit ook mogelijk vanuit een functie geladen:

voor $i ( 1 .. 10 ) {
$AoA[$i] = [ somefunc($i) ];
}

Of misschien had u een tijdelijke variabele met de array erin.

voor $i ( 1 .. 10 ) {
@tmp = somefunc($i);
$AoA[$i] = [ @tmp ];
}

Het is belangrijk dat u de arrayreferentieconstructor "[ ]" gebruikt. Dat komt omdat
dit zou niet werken:

$AoA[$i] = @tmp; # FOUT!

De reden dat dit niet doet wat u wilt, is omdat het toewijzen van een dergelijke benoemde array aan een
scalar neemt een array in scalaire context, wat betekent dat het alleen het aantal telt
elementen in @tmp.

Als je onder de 'use strict'-richtlijnen werkt (en als dat niet zo is, waarom in vredesnaam dan niet?),
Je zult een aantal verklaringen moeten toevoegen om het tevreden te stellen:

gebruik strikt;
mijn(@AoA, @tmp);
terwijl (<>) {
@tmp = gesplitst;
duw @AoA, [ @tmp ];
}

Uiteraard hoeft de tijdelijke array helemaal geen naam te hebben:

terwijl (<>) {
push @AoA, [ split ];
}

Je hoeft ook niet te gebruiken Duwen()Je zou gewoon een directe opdracht kunnen maken als je wist
waar je het wilde plaatsen:

mijn (@AoA, $i, $line);
voor $i ( 0 .. 10 ) {
$lijn = <>;
$AoA[$i] = [ split " ", $line ];
}

of zelfs gewoon

mijn (@AoA, $i);
voor $i ( 0 .. 10 ) {
$AoA[$i] = [ splitsen " ", <> ];
}

Over het algemeen moet u voorzichtig zijn met het gebruik van functies die mogelijk lijsten kunnen retourneren
scalaire context zonder dit expliciet te vermelden. Dit zou duidelijker zijn voor de gewone gebruiker.
lezer:

mijn (@AoA, $i);
voor $i ( 0 .. 10 ) {
$AoA[$i] = [ split " ", scalar(<>) ];
}

Als je een variabele $ref_to_AoA als referentie naar een array wilt hebben, moet je het volgende doen:
iets zoals dit:

terwijl (<>) {
push @$ref_to_AoA, [ split ];
}

Nu kunt u nieuwe rijen toevoegen. Hoe zit het met het toevoegen van nieuwe kolommen? Als u alleen met
Bij matrices is het vaak het makkelijkst om een ​​eenvoudige toewijzing te gebruiken:

voor $x (1 .. 10) {
voor $y (1 .. 10) {
$AoA[$x][$y] = func($x, $y);
}
}

voor $x ( 3, 7, 9 ) {
$AoA[$x][20] += func2($x);
}

Het maakt niet uit of die elementen er al zijn of niet: het creëert graag
ze voor u, waarbij u indien nodig de tussenliggende elementen op "undef" instelt.

Als je alleen iets aan een rij wilt toevoegen, zul je iets grappigers moeten doen:

# nieuwe kolommen toevoegen aan een bestaande rij
push @{ $AoA[0] }, "wilma", "betty"; # expliciete deref

Vóór Perl 5.14 kon dit niet eens gecompileerd worden:

push $AoA[0], "wilma", "betty"; # impliciete deref

Hoe komt dat? Omdat er ooit een tijd was dat het argument om Duwen() moest een echte array zijn, niet
slechts een verwijzing naar één. Dat is niet langer waar. Sterker nog, de regel met de tekst "implicit deref"
Het bovenstaande werkt prima (in dit geval) om te doen wat degene die expliciet deref zegt, deed.

De reden dat ik "in dit geval" zei, is omdat Slechts werkt omdat $AoA[0] al
een arrayreferentie had. Als je dat probeert met een ongedefinieerde variabele, krijg je een
uitzondering. Dat komt omdat de impliciete dereferentie nooit een ongedefinieerde
variabele zoals "@{ }" dat altijd zal doen:

mijn $aref = undef;
push $aref, qw(nog enkele waarden); # FOUT!
push @$aref, qw(nog een paar); # ok

Als u gebruik wilt maken van dit nieuwe impliciete dereferentiegedrag, ga dan gerust uw gang:
Het maakt code prettiger voor het oog en de pols. Houd er rekening mee dat oudere releases kunnen vastlopen.
erop tijdens het compileren. Wanneer je iets gebruikt dat alleen in sommige gevallen werkt,
Gezien de release van Perl en later, maar niet eerder, moet u een prominente plaats innemen

gebruik v5.14; # nodig voor impliciete deref van array refs door array ops

richtlijn bovenaan het bestand dat het nodig heeft. Op die manier, wanneer iemand probeert de
nieuwe code onder een oude Perl, in plaats van een fout te krijgen zoals

Het type arg 1 dat gepusht moet worden, moet een array zijn (geen array-element) op /tmp/a regel 8, in de buurt van ""betty";"
Uitvoering van /tmp/a is afgebroken vanwege compilatiefouten.

ze zullen beleefd geïnformeerd worden dat

Perl v5.14.0 vereist--dit is alleen v5.12.3, gestopt op /tmp/a regel 1.
BEGIN is mislukt--compilatie is afgebroken op /tmp/a regel 1.

Toegang en Print
Nu is het tijd om je datastructuur af te drukken. Hoe ga je dat doen? Nou, als
Als je slechts één van de elementen wilt, is het triviaal:

afdrukken $AoA[0][0];

Als je het hele ding wilt afdrukken, kun je echter niet zeggen

print @AoA; # FOUT

omdat je alleen de referenties te zien krijgt, en Perl zal nooit automatisch derefereren
dingen voor je. In plaats daarvan moet je zelf een of twee lussen rollen. Dit print het geheel
structuur, gebruikmakend van de shell-stijl voor() construeren om over de buitenste set te lussen
subscripten.

voor $aref ( @AoA ) {
zeg "\t [ @$aref ],";
}

Als u de subscripten wilt bijhouden, kunt u het volgende doen:

voor $i ( 0 .. $#AoA ) {
zeg "\t elt $i is [ @{$AoA[$i]} ],";
}

of misschien zelfs dit. Let op de binnenste lus.

voor $i ( 0 .. $#AoA ) {
voor $j ( 0 .. $#{$AoA[$i]} ) {
zeg "elt $i $j is $AoA[$i][$j]";
}
}

Zoals je ziet, wordt het een beetje ingewikkeld. Daarom is het soms makkelijker om een
tijdelijk onderweg:

voor $i ( 0 .. $#AoA ) {
$aref = $AoA[$i];
voor $j ( 0 .. $#{$aref} ) {
zeg "elt $i $j is $AoA[$i][$j]";
}
}

Hmm... dat is nog steeds een beetje lelijk. Wat dacht je van dit:

voor $i ( 0 .. $#AoA ) {
$aref = $AoA[$i];
$n = @$aref - 1;
voor $j ( 0 .. $n ) {
zeg "elt $i $j is $AoA[$i][$j]";
}
}

Als u het beu bent om een ​​aangepaste afdruk voor uw datastructuren te schrijven, kunt u kijken naar
de standaard Dumpvalue- of Data::Dumper-modules. De eerste is wat de Perl-debugger gebruikt.
gebruikt, terwijl de laatste parseerbare Perl-code genereert. Bijvoorbeeld:

gebruik v5.14; # gebruik het + prototype, nieuw in v5.14

sub tonen(+) {
vereisen Dumpvalue;
staat $prettily = nieuwe Dumpvalue::
vinkje => q("),
compactDump => 1, # plaats deze twee regels uit commentaar
veryCompact => 1, # als je een grotere dump wilt
;
dumpWaarde $prettily @_;
}

# Wijs een lijst met arrayverwijzingen toe aan een array.
mijn @AoA = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homerus", "marge", "bart" ],
);
duw $AoA[0], "wilma", "betty";
toon @AoA;

zal afdrukken:

0 0..3 "fred" "barney" "wilma" "betty"
1 0..2 "george" "jane" "elroy"
2 0..2 "homer" "marge" "bart"

Terwijl als je de twee regels die ik zei dat je misschien zou willen uitcommentariëren, het je dan wordt getoond
op deze manier:

0 ARRAY(0x8031d0)
0 "fred"
1 "barney"
2 "wilma"
3 "betty"
1 ARRAY(0x803d40)
0 "george"
1 "jane"
2 "elroy"
2 ARRAY(0x803e10)
0 "homerus"
1 "marge"
2 "bart"

Slices
Als je een plak (een deel van een rij) in een multidimensionale array wilt benaderen, moet je:
moet wat fantasierijke subscripting toepassen. Dat komt omdat we weliswaar een mooi synoniem hebben voor
afzonderlijke elementen via de aanwijzerpijl voor dereferentie, bestaat er geen dergelijk gemak voor
plakjes.

Zo voer je één bewerking uit met een lus. We gaan uit van een @AoA-variabele, net als voorheen.

@deel = ();
$ x = 4;
voor ($y = 7; $y < 13; $y++) {
push @part, $AoA[$x][$y];
}

Diezelfde lus zou vervangen kunnen worden door een slice-bewerking:

@part = @{$AoA[4]}[7..12];

of een beetje verder uit elkaar:

@part = @{ $AoA[4] } [ 7..12 ];

Maar zoals je je wel kunt voorstellen, kan dit behoorlijk heftig zijn voor de lezer.

Ah, maar wat als je een tweedimensionaal plak, zoals het laten lopen van $x van 4..8 en $y
Van 7 naar 12 rennen? Hmm... dit is de simpele manier:

@newAoA = ();
voor ($startx = $x = 4; $x <= 8; $x++) {
voor ($starty = $y = 7; $y <= 12; $y++) {
$newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
}
}

We kunnen een deel van de lusvorming door de slices verminderen

voor ($x = 4; $x <= 8; $x++) {
push @newAoA, [ @{ $AoA[$x] } [ 7..12 ] ];
}

Als je van Schwartziaanse transformaties hield, had je waarschijnlijk een kaart voor die transformatie gekozen

@newAoA = kaart { [ @{ $AoA[$_] } [ 7..12 ] ] } 4 .. 8;

Hoewel, als uw manager u ervan beschuldigt dat u via internet op zoek gaat naar baanzekerheid (of juist snel onzekerheid)
ondoorgrondelijke code, daar valt moeilijk over te twisten. :-) Als ik jou was, zou ik dat in een
functie:

@newAoA = splice_2D( \@AoA, 4 => 8, 7 => 12 );
sub-splice_2D {
mijn $lrr = shift; # ref naar array van array refs!
mijn ($x_lo, $x_hi,
$y_lo, $y_hi) = @_;

retourkaart {
[ @{ $lrr->[$_] } [ $y_lo .. $y_hi ] ]
} $x_lo .. $x_hi;
}

Gebruik Perllol online met behulp van de services van Onworks.net


Gratis servers en werkstations

Windows- en Linux-apps downloaden

Linux-commando's

Ad




×
advertentie
❤️Koop, boek of koop hier — het is gratis, en zo blijven onze diensten gratis.