2

次の形式の入力ファイルがあります

ant,1
bat,1
bat,2
cat,4
cat,1
cat,2
dog,4

結果は次のようになるため、各キー (column1) の col2 を集計する必要があります。

ant,1
bat,3
cat,7
dog,4

その他の考慮事項:

  1. 入力ファイルがソートされていると仮定します
  2. 入力ファイルがかなり大きい (約 1M 行) ため、配列を使用してメモリを占有したくない
  3. 各入力行は、読み取ったときに処理され、次の行に移動する必要があります
  4. 結果を outFile に書き込む必要があります
  5. これは Perl で行う必要がありますが、疑似コードまたはアルゴリズムでも同様に役立ちます

ありがとう!

これは私が思いついたものです...これがより良く/エレガントに書けるかどうかを見たいです。

open infile, outFile

prev_line = <infile>;
print_line = $prev_line;

while(<>){
   curr_line = $_;

   @prev_cols=split(',', $prev_line);
   @curr_cols=split(',', $curr_line);

   if ( $prev_cols[0] eq $curr_cols[0] ){
      $prev_cols[1] += curr_cols[1];
      $print_line = "$prev_cols[0],$prev_cols[1]\n";
      $print_flag = 0;
   }
   else{
      $print outFile "$print_line";
      $print_flag = 1;
      $print_line = $curr_line;
   }
   $prev_line = $curr_line;
}

if($print_flag = 1){
   print outFile "$curr_line";
}   
else{
   print outFile "$print_line";
}
4

3 に答える 3

2
#!/usr/bin/perl
use warnings;
use strict;
use integer;

my %a;
while (<>) {
    my ($animal, $n) = /^\s*(\S+)\s*,\s*(\S+)/;
    $a{$animal} += $n if defined $n;
}
print "$_,${a{$_}}\n" for sort keys %a;

この短いコードにより、Perl の優れたハッシュ機能 ( %a. ハッシュは Perl の中心です。それらなしでは流暢な Perl を書くことはできません。

ちなみに、コードが Perl の興味深い自動有効化機能を実行していることに注意してください。特定の動物が入力ストリームで最初に遭遇したとき、カウントは存在しないため、Perl は暗黙のうちに既存のカウントがゼロであると想定します。したがって、+=オペレーターは失敗する必要があるように見えても、失敗しません。最初のインスタンスでゼロに追加するだけです。

一方、データの数だけでなく、動物の数も非常に多いため、ハッシュを保存したくない場合があります%a。この場合、例のように、データが入力で動物ごとにソートされている場合にのみ、合計を計算できます。この場合、次のようなものが適しているかもしれません (残念ながら、上記ほどきちんとしたものではありません)。

#!/usr/bin/perl
use warnings;
use strict;
use integer;

my $last_animal = undef;
my $total_for_the_last_animal = 0;

sub start_new_animal ($$) {
    my $next_animal = shift;
    my $n = shift;
    print "$last_animal,$total_for_the_last_animal\n"
      if defined $last_animal;
    $last_animal = $next_animal;
    $total_for_the_last_animal = $n;
}

while (<>) {
    my ($animal, $n) = /^\s*(\S+)\s*,\s*(\S+)/;
    if (
        defined($n) && defined($animal) && defined($last_animal)
          && $animal eq $last_animal
    ) { $total_for_the_last_animal += $n; }
    else { start_new_animal $animal, $n; }
}
start_new_animal undef, 0;
于 2012-06-08T01:40:43.377 に答える
1

Perl のawkモードを使用します。

  • -a

-nまたはと一緒に使用すると、自動分割モードがオンになります-p。配列に対する暗黙的なsplitコマンドは、 orによって生成される暗黙的なループ@F内で最初に実行されます。while-n-p

perl -ane 'print pop(@F), "\n";'

と同等です

while (<>) {
  @F = split(' ');
  print pop(@F), "\n";
}

を使用して代替区切り文字を指定できます-F

あとは、合計をハッシュに蓄積して出力するだけです。

$ perl -F, -lane '$s{$F[0]} += $F[1];
    END { print "$_,$s{$_}" for sort keys %s }' input

出力:

アリ、1
コウモリ、3
猫、7
犬、4
于 2012-06-08T02:49:22.007 に答える
0

perl では簡単です。ファイル入力をループします。入力行をコンマで分割します。列 1 の各キーについて、列 2 の値を追加するハッシュを保持します。ファイルの最後に、ハッシュ キーとその値のリストを出力します。1 行で実行できますが、アルゴリズムがわかりにくくなります。

于 2012-06-08T01:44:17.233 に答える