4

次の内容を含む 2 つのテキスト ファイルがあります。

FILE1.txt

dog
cat
antelope

FILE2.txt

1
2
Barry

私が達成したい出力は次のとおりです。

dog1
dog2
dogBarry
cat1
cat2
catBarry
antelope1
antelope2
antelopeBarry

彼らは私がそれについて行った方法です:

    open (FILE1, "<File1.txt") || die $!;
    open (FILE2, "<File2.txt") || die $!;

    my @animals = (<FILE1>);  #each line of the file into an array
    my @otherStrings = (<FILE2>);   #each line of the file into an array

    close FILE1 || die $!;
    close FILE2 || die $!;

    my @bothTogether;
    foreach my $animal (@animals) {
    chomp $animal;
            foreach my $otherString (@otherStrings) {
                    chomp $otherString;
                    push (@bothTogether,  "$animal$otherString");
            }
   }
   print @bothTogether; 

私が行った方法はうまくいきますが、特に両方のファイルに数千行が含まれている可能性がある場合、それは最善の方法ではないと確信していますか?

おそらくハッシュを使用するために、これを行う最良の方法は何でしょうか?

4

2 に答える 2

5

あなたのアプローチは、数千行のファイルに対してうまく機能します。それは本当にそれほど大きくはありません。数百万行の場合、問題になる可能性があります。

ただし、1つのファイルをメモリに読み込むだけで、結果を配列に格納する代わりにすぐに出力することで、コードのメモリ使用量を減らすことができます。

use warnings;
use strict;

open my $animals, '<', 'File1.txt' or die "Can't open animals: $!";
open my $payloads, '<', 'File2.txt' or die "Can't open payloads: $!";

my @payloads = <$payloads>;   #each line of the file into an array
close $payloads or die "Can't close payloads: $!";

while (my $line = <$animals>) {
    chomp $line;
    print $line.$_ foreach (@payloads);
}
close $animals or die "Can't close animals: $!";

同じサイズの2つの巨大なファイルでは、これは元のコードの約1/4のメモリを使用します。

更新:コードを編集して、コードを最新化するためのSimbabqueの優れた提案を含めました。

更新2:他の人が指摘しているように、動物ファイルの各行でペイロードファイルを1行ずつ調べて、どちらのファイルもメモリに読み込むことはできません。ただし、それははるかに遅くなります。どうしても必要な場合を除いて、避ける必要があります。私が提案したアプローチは、元のコードとほぼ同じ速度になります。

于 2013-02-06T13:07:21.337 に答える
1

特定の Modern Perl の側面 (openたとえば 2 つの引数) を除けば、コードは非常に単純です。

私が見ることができる唯一の改善点は、内部chompを余分なループに移動できることです。おそらく、ファイルの読み取り中にチョッピングを行うことができます。それはいくらかの時間を節約するでしょう。しかし、全体として、他のデータの各行のデータで何かをしたい場合は、それを正しく行っています。

or die優先順位のために代わりに使用する必要|| dieがあります。配列の項目に改行がないため、最終的な出力は長い行になります。

更新: @FrankB は上記のコメントで良い提案をしました: ファイルが巨大で、メモリに苦労している場合は、ファイルを丸呑みして 2 つの配列に入れるのではなく、最初の 1 行を読み取って処理する必要があります。そして、これらの最初の行のそれぞれについて、2 番目の行を開いて読んでください。これにはかなり時間がかかりますが、大量のメモリを節約できます。次に、結果配列に結果をプッシュする代わりに、結果を直接出力します。

于 2013-02-06T12:59:45.500 に答える