Bu, Ubuntu Online, Fedora Online, Windows çevrimiçi emülatörü veya MAC OS çevrimiçi emülatörü gibi birden fazla ücretsiz çevrimiçi iş istasyonumuzdan birini kullanarak OnWorks ücretsiz barındırma sağlayıcısında çalıştırılabilen perllol komutudur.
Program:
ADI
perllol - Perl'de Dizilerin Dizilerini Değiştirme
AÇIKLAMA
Beyan ve giriş of Diziler of Diziler
Perl'de oluşturulacak en basit iki seviyeli veri yapısı, bazen bir dizi dizidir.
gelişigüzel bir liste listesi denir. Anlaşılması oldukça kolay ve neredeyse
Burada geçerli olan her şey, daha sonra meraklı verilerle de geçerli olacaktır.
yapıları.
Bir dizi dizisi, iki ile elde edebileceğiniz normal bir eski @AoA dizisidir.
$AoA[3][2] gibi abonelikler. İşte dizinin bir beyanı:
5.010 kullanın; # böylece say() kullanabiliriz
# dizimize bir dizi referans dizisi ata
@AoA = (
[ "fred", "barney", "çakıl taşları", "bambam", "dino", ],
[ "george", "jane", "elroy", "judy", ],
[ "homer", "bart", "marge", "maggie", ],
);
$AoA[2][1] deyin;
baronet
Şimdi dış braket tipinin yuvarlak, yani bir
parantez. Bunun nedeni, bir @array atadığınız için parantez kullanmanız gerekir. Eğer
orada istedin değil @AoA olmak yerine, sadece ona bir referans olmak
bunun gibi bir şey daha:
# dizi referansları dizisine bir referans atayın
$ref_to_AoA = [
[ "fred", "barney", "çakıl taşları", "bambam", "dino", ],
[ "george", "jane", "elroy", "judy", ],
[ "homer", "bart", "marge", "maggie", ],
];
$ref_to_AoA->[2][1] deyin;
baronet
Dış köşeli ayraç türünün değiştiğine ve dolayısıyla erişim sözdizimimizin de değiştiğine dikkat edin.
Bunun nedeni, C'den farklı olarak, Perl'de dizileri ve referansları özgürce değiştiremezsiniz.
buna. $ref_to_AoA bir diziye referanstır, @AoA ise uygun bir dizidir.
Benzer şekilde, $AoA[2] bir dizi değil, bir dizi referansıdır. Peki bunları nasıl yazabilirsiniz:
$AoA[2][2]
$ref_to_AoA->[2][2]
bunları yazmak zorunda kalmak yerine:
$AoA[2]->[2]
$ref_to_AoA->[2]->[2]
Bunun nedeni, kuralın yalnızca bitişik parantezlerde (ister kare ister kıvrımlı olsun),
işaretçi referans kaldırma okunu atlamakta özgürsünüz. Ama bunu çok için yapamazsın
ilki, referans içeren bir skaler ise, bu, $ref_to_AoA'nın her zaman olduğu anlamına gelir
buna ihtiyacı var.
Büyüyen kg Kendi
Sabit bir veri yapısının bildirilmesi için her şey yolunda ve iyi, ama ya isterseniz
anında yeni öğeler eklemek mi yoksa tamamen sıfırdan oluşturmak mı?
İlk önce, bir dosyadan okumaya bakalım. Bu, bir satıra satır eklemek gibi bir şeydir.
zaman. Her satırın bir satır ve her kelimenin bir olduğu düz bir dosya olduğunu varsayacağız.
öğe. Tüm bunları içeren bir @AoA dizisi geliştirmeye çalışıyorsanız, işte doğru
bunu yapmanın yolu:
süre (<>) {
@tmp = bölme;
@AoA'ya basın, [ @tmp ];
}
Bunu bir fonksiyondan da yüklemiş olabilirsiniz:
$i için ( 1 .. 10 ) {
$AoA[$i] = [ bir işlev($i) ];
}
Veya içinde diziyle birlikte oturan geçici bir değişkeniniz olabilir.
$i için ( 1 .. 10 ) {
@tmp = bir işlev($i);
$AoA[$i] = [ @tmp ];
}
"[ ]" dizi başvuru oluşturucusunu kullandığınızdan emin olmanız önemlidir. O yüzden
bu işe yaramaz:
$AoA[$i] = @tmp; # YANLIŞ!
İstediğinizi yapmamasının nedeni, böyle adlandırılmış bir diziyi bir diziye atamaktır.
skaler, skaler bağlamda bir dizi alıyor, bu da sadece sayısını saydığı anlamına geliyor.
@tmp'deki öğeler.
"Kullanım katı" altında çalışıyorsanız (ve değilseniz, neden dünyada değilsiniz?),
mutlu etmek için bazı beyanlar eklemeniz gerekecek:
sıkı kullanın;
benim(@AoA, @tmp);
süre (<>) {
@tmp = bölme;
@AoA'ya basın, [ @tmp ];
}
Elbette, bir ada sahip olmak için geçici diziye ihtiyacınız yok:
süre (<>) {
@AoA'ya basın, [ bölme ];
}
Ayrıca kullanmak zorunda değilsin it(). Eğer bilseydin, doğrudan bir atama yapabilirdin.
nereye koymak istedin:
benim (@AoA, $i, $satır);
$i için ( 0 .. 10 ) {
$satır = <>;
$AoA[$i] = [ böl " ", $satır ];
}
hatta sadece
benim (@AoA, $i);
$i için ( 0 .. 10 ) {
$AoA[$i] = [ böl " ", <> ];
}
Genel olarak, potansiyel olarak listeleri döndürebilecek işlevleri kullanmaktan çekinmelisiniz.
skaler bağlamı açıkça belirtmeden. Bu sıradan insanlar için daha net olurdu
okuyucu:
benim (@AoA, $i);
$i için ( 0 .. 10 ) {
$AoA[$i] = [ böl " ", skaler(<>) ];
}
Bir diziye referans olarak $ref_to_AoA değişkenine sahip olmak istiyorsanız, yapmanız gerekir.
böyle bir şey:
süre (<>) {
@$ref_to_AoA'ya basın, [ bölme ];
}
Artık yeni satırlar ekleyebilirsiniz. Yeni sütunlar eklemeye ne dersiniz? sadece uğraşıyorsanız
matrisler, basit atamayı kullanmak genellikle en kolayıdır:
$x için (1 .. 10) {
$y için (1 .. 10) {
$AoA[$x][$y] = işlev($x, $y);
}
}
$x için ( 3, 7, 9 ) {
$AoA[$x][20] += func2($x);
}
Bu öğelerin zaten orada olup olmadığı önemli değil: memnuniyetle yaratacaktır.
bunları sizin için, araya giren öğeleri gerektiği gibi "undef" olarak ayarlayın.
Yalnızca bir satıra eklemek istiyorsanız, biraz daha komik görünen bir şey yapmanız gerekir:
# mevcut bir satıra yeni sütunlar ekle
@{ $AoA[0] }, "wilma", "betty"; # açık deref
Perl 5.14'ten önce bu, derlenmiyordu bile:
$AoA[0], "wilma", "betty" tuşlarına basın; # örtük deref
Nasıl olur? Çünkü bir zamanlar, argüman it() gerçek bir dizi olmalı, değil
sadece birine referans. Bu artık doğru değil. Aslında, "örtük deref" olarak işaretlenmiş satır
yukarıdakiler gayet iyi çalışıyor - bu örnekte - açık deref yazanın yaptığını yapmak için.
"Bu durumda" dememin nedeni, bir tek $AoA[0] zaten çalıştığı için
bir dizi referansı tuttu. Bunu tanımsız bir değişken üzerinde denerseniz,
istisna. Bunun nedeni, örtük referansın hiçbir zaman tanımsız bir şeyi otomatik olarak canlandırmayacağıdır.
"@{ }" şeklindeki değişken her zaman:
benim $aref = undef;
$aref, qw(birkaç değer daha); # YANLIŞ!
@$aref'e basın, qw(birkaç tane daha); # Tamam
Bu yeni örtük referans kaldırma davranışından yararlanmak istiyorsanız, hemen devam edin:
kodu göz ve bilek için kolaylaştırır. Sadece eski sürümlerin boğulacağını anlayın
derleme sırasında üzerinde. Sadece bazılarında işe yarayan bir şeyden faydalandığınızda
Perl'in piyasaya sürülmesi ve daha sonra, ancak daha önce değil, öne çıkan bir
v5.14'ü kullanın; # dizi operasyonları tarafından dizi referanslarının örtük deref'i için gerekli
ihtiyacı olan dosyanın en üstündeki yönerge. Bu şekilde biri çalıştırmaya çalıştığında
gibi bir hata almak yerine eski bir perl altında yeni kod
Gönderilecek argüman 1 türü, /tmp/a satırı 8'de, ""betty";" yakınında dizi (dizi öğesi değil) olmalıdır;
/tmp/a'nın yürütülmesi derleme hataları nedeniyle durduruldu.
Kibarca bilgilendirilecekler
Perl v5.14.0 gerekli--bu yalnızca v5.12.3'tür, /tmp/a satır 1'de durdurulmuştur.
BEGIN başarısız oldu-- /tmp/a satırında derleme iptal edildi.
giriş ve Baskı
Şimdi veri yapınızı yazdırmanın zamanı geldi. Bunu nasıl yapacaksın? Peki, eğer
unsurlardan sadece birini istiyorsun, önemsiz:
$AoA[0][0] yazdır;
Her şeyi yazdırmak istersen, yine de söyleyemezsin.
@AoA yazdır; # YANLIŞ
çünkü yalnızca listelenen referansları alacaksınız ve Perl hiçbir zaman otomatik olarak referansı kaldırmayacaktır.
senin için şeyler. Bunun yerine, kendinize bir veya iki döngü atmanız gerekir. Bu, tamamını yazdırır
kabuk stilini kullanarak yapı için() dış kümesi boyunca döngü oluşturmak için
abonelikler.
$aref için ( @AoA ) {
"\t [ @$aref ]," deyin;
}
Abonelikleri takip etmek istiyorsanız, şunu yapabilirsiniz:
$i için ( 0 .. $#AoA ) {
say "\t elt $i [ @{$AoA[$i]} ],";
}
ya da belki bu bile. İç döngüye dikkat edin.
$i için ( 0 .. $#AoA ) {
$j için ( 0 .. $#{$AoA[$i]} ) {
"elt $i $j, $AoA[$i][$j]'dir" deyin;
}
}
Gördüğünüz gibi, biraz karmaşıklaşıyor. Bu yüzden bazen almak daha kolaydır
geçerken geçici:
$i için ( 0 .. $#AoA ) {
$aref = $AoA[$i];
$j için ( 0 .. $#{$aref} ) {
"elt $i $j, $AoA[$i][$j]'dir" deyin;
}
}
Hmm... bu hala biraz çirkin. Buna ne dersin:
$i için ( 0 .. $#AoA ) {
$aref = $AoA[$i];
$n = @$aref - 1;
$j için ( 0 .. $n ) {
"elt $i $j, $AoA[$i][$j]'dir" deyin;
}
}
Veri yapılarınız için özel bir baskı yazmaktan yorulduğunuzda, şuna bakabilirsiniz:
standart Dumpvalue veya Data::Dumper modülleri. Birincisi, Perl hata ayıklayıcısının
kullanır, ikincisi ayrıştırılabilir Perl kodu üretir. Örneğin:
v5.14'ü kullanın; # + prototipini kullanarak, v5.14'te yeni
alt gösteri(+) {
Dumpvalue gerektirir;
durum $güzel = yeni Dumpvalue::
tik => q("),
compactDump => 1, # bu iki satırı yorumlayın
veryCompact => 1, # daha büyük bir döküm istiyorsanız
;
dumpValue $güzel @_;
}
# Bir diziye dizi referanslarının bir listesini atayın.
@AoA'm = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
);
$AoA[0], "wilma", "betty" tuşlarına basın;
@AoA'yı göster;
yazdıracak:
0 0..3 "fred" "barney" "wilma" "betty"
1 0..2 "george" "jane" "elroy"
2 0..2 "homer" "marge" "bart"
Oysa isteyebileceğinizi söylediğim iki satırı yorumlarsanız, o zaman size gösterir.
bunun yerine bu şekilde:
0 DİZİ(0x8031d0)
0 "fred"
1 "barney"
2 "villa"
3 "bet"
1 DİZİ(0x803d40)
0 "George"
1 "jan"
2 "elroy"
2 DİZİ(0x803e10)
0 "ev"
1 "marj"
2 "bart"
Dilimler
Çok boyutlu bir dizide bir dilime (bir satırın parçası) ulaşmak istiyorsanız,
bazı süslü abonelik yapmak zorunda. Çünkü güzel bir eş anlamlımız varken
referans kaldırma için işaretçi oku aracılığıyla tek öğeler, için böyle bir kolaylık yoktur
dilimler.
İşte bir döngü kullanarak bir işlemin nasıl yapılacağı. Daha önce olduğu gibi bir @AoA değişkeni varsayacağız.
@bölüm = ();
$ x = 4;
for ($y = 7; $y < 13; $y++) {
@part'a basın, $AoA[$x][$y];
}
Aynı döngü bir dilim işlemiyle değiştirilebilir:
@part = @{$AoA[4]}[7..12];
veya biraz aralıklı:
@part = @{ $AoA[4] } [ 7..12 ];
Ancak tahmin edebileceğiniz gibi, bu okuyucu için oldukça zor olabilir.
Ah, ama ya bir iki boyutlu dilim, örneğin $x'in 4..8 ve $y'den kaçması gibi
7'den 12'ye kaç? Hmm... işte basit yol:
@yeniAoA = ();
for ($startx = $x = 4; $x <= 8; $x++) {
for ($starty = $y = 7; $y <= 12; $y++) {
$newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
}
}
Dilimler arasındaki döngünün bir kısmını azaltabiliriz
for ($x = 4; $x <= 8; $x++) {
it @newAoA, [ @{ $AoA[$x] } [ 7..12 ] ];
}
Schwartzian Transforms ile ilgilenseydiniz, muhtemelen bunun için haritayı seçerdiniz.
@newAoA = harita { [ @{ $AoA[$_] } [ 7..12 ] ] } 4 .. 8;
Yöneticiniz sizi iş güvenliği (veya hızlı güvensizlik) aramakla suçlasa da
esrarengiz kod, tartışmak zor olurdu. :-) Yerinde olsam bunu bir
işlevi:
@newAoA = splice_2D( \@AoA, 4 => 8, 7 => 12);
alt ekleme_2D {
benim $lrr = vardiyam; # ref dizi refs dizisine!
benim ($x_lo, $x_hi,
$y_lo, $y_hi) = @_;
dönüş haritası {
[ @{ $lrr->[$_] } [ $y_lo .. $y_hi ] ]
} $x_lo .. $x_hi;
}
onworks.net hizmetlerini kullanarak perllol'ü çevrimiçi kullanın