0

1 つの配列 (@array1) のすべての要素を処理するループを作成し、別の配列 (@array2) に同じ要素が見つかった場合は、3 番目の配列 (@array3) から値を取得したいと考えています。同じインデックスが最初の配列に追加され、3 番目の配列から削除されます。私はこの方法で試しましたが、if ステートメントの行は初期化された値で実行され、永遠にループします。

    foreach my $elem1 (@array1){
        my $i = 0;
        while ($i < scalar @array2){
            if($array2[$i]==$elem1){
                push (@array1, $array3[$i]);
                delete $array2[$i];
            }
            else{
                $i++;
            }
        }
    }
4

3 に答える 3

1

問題は、要素が一致する場合に $i をインクリメントしないことです。を削除しelseます。

于 2013-05-09T13:51:25.457 に答える
1

さて、これが問題に対処する 1 つの方法です (あなたが何をしたいのかを私が理解している範囲で)。メンバーシップに関する質問に答える必要があるときはいつでも、おそらくハッシュを使用したいと思うでしょう。

use strict;
use warnings;

my @array1 = ( 11, 22, 33,  44);
my @array2 = ( 11,  2,  3,  44,  5,   44);
my @array3 = (-11, -2, -3, -44, -5, -444);

# Keep track of every value in @array1.
my %vals = map { $_ => 1 } @array1;

my @keep_indexes;

# Go through @array2, either adding the corresponding
# value in @array3 to @array1 or storing the array index.
for my $i (0 .. $#array2) {
    if ($vals{$array2[$i]}){
        push @array1, $array3[$i];
    }
    else {
        push @keep_indexes, $i;
    }
}

# Rebuild @array3 from the indexes that we stored.
# Change this to @array2 if you want to delete from that array instead.
@array3 = map $array3[$_], @keep_indexes;

print join(' ', @array1), "\n"; # 11 22 33 44 -11 -44 -444
print join(' ', @array2), "\n"; # 11 2 3 44 5 44
print join(' ', @array3), "\n"; # -2 -3 -5

私はそのコードが嫌いなので、いくつかの注意点があります:

  • 変数名 ( 、 など) に番号を付ける@array1@array2、混乱が生じます。より良い変数名、またはより良いデータ構造が必要です。
  • 並列配列を維持するビジネスに従事していることに気付いたときはいつでも、より良いデータ構造が役立つかどうかを検討する必要があります。
于 2013-05-09T14:39:21.187 に答える
0

質問に記載されているように、array3 ではなく、array2 から要素を削除しています。削除操作で配列要素が に設定されると思いますundef。次回のループで、現在undef$elem に対してある同じ要素をチェックします。したがって、エラー。それから彼は何度も同じことをします。

于 2013-05-09T13:52:52.487 に答える