1

「データ 1」と「データ 2」の 2 つのデータ セットがあります。「データ 1」の各ポジの値について、ポジが Star_posi と end_posi の間にある「データ 2」の範囲を見つけるのを手伝ってくれませんか。

データ 1

  Num     posi 
   1        2 
   2        14
   3        18
   4        19
  ...      ...

データ 2

 Num      Star_posi    End_posi
  1          1            10
  2          3            15
  3          17           21
  4          23           34
 ...       ...           ...

出力

  1. star_posi 1 と end_posi 10 の間の Data 2 に含まれる、posi 2 の Data 1。
  2. star_posi 3 と end_posi 15 の間の Data 2 に含まれる、posi 14 の Data 1。

Data 1 の値が Data 2 の行の範囲に含まれる Data 2 の行を特定したい。以下のスクリプトを作成しましたが、うまくいきませんでした。

   #!/usr/bin/perl -w
   use strict;
   use warnings;
   use Data:ump qw(dump);

   #Sort the position**************

   my (@posi1, $Num2, @Num2, @Num1);
   open(POS1,"<posi.txt");
   @posi1=<POS1>;
   @Num1=@posi1;
   open(LIST,">list.txt"); {
   @Num2= sort {$a <=> $b} @Num1;
   $Num2 = join( '', @Num2);
   print $Num2;
   print LIST $Num2."\n";
   }
   close(LIST); 

参考になれば幸いです。

4

2 に答える 2

3

あなたのコードは混乱しています。また、それはあなたの問題に決して対処しません。

あなたがしたいのはsplit、ファイルからの行をwhileループしてハッシュに保存することです。値を取得したら、演算子<と演算子を使用してそれらを簡単に比較して>、どの範囲に収まるかを確認できます。

use strict;
use warnings;
use autodie;

my (%data1,%data2);


open my $in, '<', 'data1.txt';
while (<$in>) {
    next unless /^\s*\d/;
    my ($num, $posi) = split;
    $data1{$num} = $posi;
}

open $in, '<', 'data2.txt';
while (<$in>) {
    next unless /^\s*\d/;
    my ($num, $star, $end) = split;
    $data2{$num}{'star'} = $star;
    $data2{$num}{'end'}  = $end;
}
close $in;

next数字で始まらない行、たとえばヘッダーや空の行、その他データに含めたくないものはスキップ ( ) していることに注意してください。

これで、ハッシュに値が含まれ、必要なテストを実行できるようになります。例えば:

for my $num (keys %data1) {
    my $val = $data1{$num};
    for my $num2 (keys %data2) {
        my $min = $data2{$num2}{'star'};
        my $max = $data2{$num2}{'end'};
        if ( ($val > $min) and ($val < $max) ) {
            print "Data 1 at posi $val contained in Data 2 between star_posi $min and end_posi $max.\n";
            last;
        }
    }
}

幸運を!

于 2011-08-24T01:06:52.437 に答える
2

Tie::RangeHashと呼ばれる CPAN モジュールを見てください。これは、まさにこの種の問題のためのものです。

use Tie::RangeHash;
my $hour_name = new Tie::RangeHash Type => Tie::RangeHash::TYPE_NUMBER;

$hour_name->add(' 0, 5', 'EARLY');
$hour_name->add(' 6,11', 'MORNING');
$hour_name->add('12,17', 'AFTERNOON');
$hour_name->add('18,23', 'EVENING');

# and in a loop elsewhere...
my $name = $hour_name->fetch($hour) || "UNKNOWN";
于 2011-08-24T07:36:02.920 に答える