1

次のファイルがあります。

a b 5
c d 6
e f 7
g h 4
i j 3
k l 10

そして、どの行が 3 列目に最小値を示しているかを見つけて、初期ファイルから消去したいと考えています。この後、もう一度プログラムを繰り返して、どの行が最小値を示しているかをもう一度見つけて、同じことをあと 2 回行いたいと思います。

出力ファイルは

c d 6
e f 7
k l 10

次のコードを書いてみました。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $file1 = "try.dat";
open my $fg,  "<", $file1 or die "Error during $file1 opening: $!";

my @vector;

while (<$fg>) {
    push @vector, [ split ];
}

my $minimum = $vector[0][2];
my @blacklist;
for my $i (0 .. $#vector) {
    if ($minimum > $vector[$i][2]){
    $minimum = $vector[$i][2];
    push @blacklist, @vector[$i+1]; 
    }
}
#say "my minimum is $minimum";
#say "the blacklist is composed by @blacklist";

に含まれる要素@blacklist(最初のケースではi j 3) を消去する方法と、すべてを反復する方法がわかりません。

反復の助けはありますか?

4

3 に答える 3

2

このようなものは、そのTie::Fileために作られたものです。結合された配列を変更することにより、ファイルをその場で変更できます。

このプログラムはあなたが望むことをします。ヘルパー関数minidxは、渡された配列の要素のうち最小値を保持する要素の最初のインデックスを返します。

このプログラムは、ファイル records の 3 番目のフィールドを array にコピーし@field3、そこから最小値のインデックスを見つけることによって機能します。そのインデックスの要素は、ファイルと@field3使用の両方から削除されますsplice

use strict;
use warnings;

use Tie::File;

tie my @file, 'Tie::File', 'file.txt' or die $!;

my @field3 = map { (split)[2] } @file;
for (1 .. 3) {
  my $i = minidx(\@field3);
  splice @file, $i, 1;
  splice @field3, $i, 1;
}

sub minidx {
  my ($arr) = @_;
  my ($i, $v);
  for (0 .. $#$arr) {
    ($i, $v) = ($_, $arr->[$_]) unless defined $v and $arr->[$_] >= $v;
  }
  return $i;
}

出力

c d 6
e f 7
k l 10
于 2013-03-14T18:25:30.343 に答える
1

アレイ@blacklist = @vector全体をブラックリストに追加していると言うとき。@vectorあなたはおそらくやりたいと思うでしょうpush @blacklist, $vector[$i]。これにより、配列参照がブラックリストにプッシュされます。

現在、blacklist には配列 ref が含まれているため、表示するにはそれを参照する必要があります。

say "the blacklist is composed by @{$blacklist[0]}";

編集:反復と書き込みの場合:

配列をスキップし@blacklist(他の目的で必要でない限り)、最小値を から削除します@vector。次に@vector、いくつかのファイルに書き込むことができます。

my $num_elts_to_remove = 3;
for (my $j = 0; $j < $num_elts_to_remove; $j++) {
  my $minimum = $vector[0][2];
  my $min_idx = 0;
  for my $i (0 .. $#vector) {
      if ($minimum > $vector[$i][2]){
        $minimum = $vector[$i][2];
        $min_idx = $i;
      }
  }
  push @blacklist, $vector[$min_index];
  splice @vector, $min_idx, 1; #remove array with smallest value
}

配列をファイルに書き込む

open OUT, ">", $outfile or die "Error: $!";
foreach(@vector) {
    print OUT join " ", @$_;
    print OUT "\n";
}
close(OUT);

版画:

c d 6
e f 7
k l 10
于 2013-03-14T17:18:53.147 に答える