0

10個の数字を含む配列があります。配列インデックス 0,2,4,6,8 の数値を選択し、それらを新しい配列に入れたいと考えています。同様に、インデックス 1,3,5,7,9 を使用します。Perl は初めてです (数日前に始めました)。

私のプログラム:

my @b;
@a = (1,2,3,4,5,6,7,8,9,10);
for($i=0;$i<=$#a;$i++)
   {
    push(@b,$a[$i+1]);
   }
print "@b";

私は何を間違っていますか?

4

5 に答える 5

2

forループの使用方法のどこかで間違いを犯しやすいので、ループを避けることをお勧めします。foreach

my @a = (1,2,3,4,5,6,7,8,9,10);

my (@even, @odd);
foreach my $i (0 .. $#a) {

  if ($i % 2) { push @odd, $a[$i] } else { push @even, $a[$i] }
}

を使用して、配列インデックス モジュロ2mapをテストしてから、次を使用してフィルター処理するか、値を取得するかを決定することもできます。%@even()$a[$_]

my @even = map { $_%2 ? () : $a[$_] } 0 .. $#a;
my @odd = map {  $_%2 ? $a[$_] : () } 0 .. $#a;
于 2013-06-12T21:08:33.903 に答える
1

平:

for($i=0;$i<=$#a;$i+=2)
   {
    push(@b,$a[$i]);
   }

奇数:

for($i=1;$i<=$#a;$i+=2)
   {
    push(@b,$a[$i]);
   }
于 2013-06-12T21:09:58.687 に答える
1

いくつかのこと:

  • プラグマuse strict;とを使用しますuse warnings;。これらは多くのエラーをキャッチします。を使用する場合use strict;は、変数を で宣言する必要がmyあります ( を使用することもありますがour、99% の場合は を使用しますmy) 。
  • ループでは、forデフォルトの変数を使用しています$_。この変数は、さまざまな理由で悪です。(1つは、スコープがグローバルであるため、他の何かがこの変数を変更する可能性があり、わかりません。)を使用する必要がある場合を除き、変数を宣言します$_
  • 標準では、と を{並べて配置します。もう 1 つは、for ループを回避することです (そして、これが単なるエイリアスであることを回避します) 。forwhileC styleforeachfor
  • スペースを使用します。$i <= $#aよりもはるかに読みやすいです$i<=$a

あなたのプログラムの私の解釈は次のとおりです。

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);  #A nicer 'print'

my @a = qw(12 13 14 15 16 17 18 19 20);
my @even;
my @odd;

for my $element (0..$#a) {
if ( $element % 2 ) {
    push @odd, $a[$element];
}
else {
    push @even, $a[$element];
}
}
say '@even = ' . join ': ', @even;
say '@odd = ' . join ': ', @odd;

出力:

@even = 12: 14: 16: 18: 20
@odd = 13: 15: 17: 19
  • for私のループに注意してください。を使用し0..$#aて、配列の各要素を調べます。is は、配列の最後の$#インデックスを返します。これは、使用した よりも理解しやすいことに注意してfor($i=0;$i<=$#a;$i++)ください。これが、C スタイルの for ループが推奨されない理由の 1 つです。
  • モジュロ演算子を使用して%、偶数/奇数を解析します。Modulo は剰余除算のようなものです。数値が奇数の場合、モジュロ% 2は 1 になります。それ以外の場合はゼロです。モジュロ演算は、サイクルで機能するものすべてに最適です。

しかし、プログラムに戻りましょう。これは、いくつかの微調整を加えた元のコードです。

  • と を追加しましuse strict;use warnings;。これらは、プログラミング エラーの約 99% をキャッチします。
  • デバッグに関しては、より良いuse feature qw(say);ので使用します。sayステートメントを取得してコピーし、そのqq(...);周りに言葉を投げかけて、それが何をしているかを確認できます。
  • sayコードのロジックを明らかにするために、一連のステートメントを追加しました。

何が起こるか見てみましょう。少し変更したプログラムは次のとおりです。

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);

my @b;
my @a = (1,2,3,4,5,6,7,8,9,10);
my $i;
for($i=0; $i<=$#a; $i++) {
    say "Index = $i  Element = $a[$i + 1]";
    say qq(push(\@b, $a[$i+1]););
    push(@b,$a[$i+1]);
}
print "@b";

出力は次のとおりです。

Index = 0  Element = 2
push(@b, 2);
Index = 1  Element = 3
push(@b, 3);
Index = 2  Element = 4
push(@b, 4);
Index = 3  Element = 5
push(@b, 5);
Index = 4  Element = 6
push(@b, 6);
Index = 5  Element = 7
push(@b, 7);
Index = 6  Element = 8
push(@b, 8);
Index = 7  Element = 9
push(@b, 9);
Index = 8  Element = 10
push(@b, 10);
Use of uninitialized value in concatenation (.) or string at ./test.pl line 11.
Index = 9  Element = 
Use of uninitialized value within @a in concatenation (.) or string at ./test.pl line 12.
push(@b, );
Use of uninitialized value $b[9] in join or string at ./test.pl line 15.

各ステートメントがどのようpushに実行されているかを見ることができます。それを見ると、すべての要素を押し込んでいます。実際、あなた$a[$i+1]がプッシュしているものとして使用したからではありません。

を使用すると、存在しないものを配列use warningsにプッシュしようとしていることがわかります。$a[10]@b

forループを変更して、他のすべての要素に移動しましょう

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);

my @b;
my @a = qw(1 2 3 4 5 6 7 8 9 10);
my $i;
for ($i=0; $i <= $#a; $i += 2) {
    push @b, $a[$i];
}

最初の要素は$a[0]. ループ内の次の要素は、単にインクリメントするのではなく、インデックス$a[2]に追加したためです。ここで、すべての偶数要素を調べて、すべての奇数要素をスキップします。21

そして出力:

1 3 5 7 9

12($a[0] = 1 であることに注意してください。これが、すべて奇数であることに注意してください。これが、プログラムで開始した理由であり、偶数である $a[0] = 12 です)。

私の好みは、構造を使用しwhileて回避するfor(...; ...; ...)ことです。

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);

my @b;
my @a = qw(1 2 3 4 5 6 7 8 9 10);
my $i = 0;
while ( $i < $#a ) {
    push @b, $a[$i];
    $i += 2;
}
于 2013-06-13T04:15:04.127 に答える
1

List::MoreUtils機能がありindexesます:

use List::MoreUtils qw{indexes} ;
use 5.10.0 ;                                              
my @a = (1,2,3,4,5,6,7,8,9,10) ; 

# index of array where even
say foreach indexes { $_ % 2 == 0 } @a ;

# index of array where odd
say foreach indexes { $_ % 2 != 0 } @a ;

私はこれが一種の洗練されていないことを認めます。また、ここでモジュール (特に CORE に含まれていないモジュール) を使用するのは不正行為である可能性があります。List::MoreUtils とが 1 つの CORE モジュールであると便利ですList::Utilsが、ここでの他の回答ほどエレガントではありません。

于 2013-06-13T04:15:05.953 に答える