はじめまして、皆様のお知恵を拝借したく投稿しました。
よろしくお願いします。

perlでのデータ処理で入力ファイルが
---------------------------------
start end
1 4
6 10
12 16
14 20
22 25
---------------------------------
となっている場合、4行目の開始位置が3行目の終了位置よりも
前になっているデータがあるとします。
(領域14~16までが領域が重複しているという意味です)。

この重複している領域部分を統合して
---------------------------------
start end
1 4
6 10
12 20
22 25
---------------------------------
と再出力できるようにperlでコーディングしたいのですが
どのようにしたらよいのでしょうか?

ご助言いただけますと幸いです

A 回答 (2件)

start と end の中間の数字も1つの配列に入れ、並べ替えて、隣り合う2つの数字を比較して、


差が 2 以上ある場合は、前の数字を範囲の終わり、後の数字を範囲の始まりとして出力しています。

use strict;
my @list = (1 .. 4, 6 .. 10, 12 .. 16, 14 .. 20, 22 .. 25);
@list = sort { $a <=> $b } @list;
print "$list[0] ";
my $p = $list[0];

foreach my $n (@list[1 .. $#list]) {
print "$p\n$n " if $n - $p >= 2;
$p = $n;
}

print "$list[$#list]\n";
    • good
    • 0
この回答へのお礼

なるほど、こんなにシンプルにまとめられることもできるんですね。
まったく思いつきませんでした

ありがとうございます

お礼日時:2007/12/19 10:02

単に「ある区間の開始位置が別の区間の終了位置より前にあったら (適切に) マージする」だけかなぁ? 動いているような気はするけどちょっと不安. あと, 「区間」の考え方によっては変更が必要です.



#!/usr/bin/perl
my @ranges = (
[1, 4],
[6, 10],
[12, 16],
[14, 20],
[22, 25],
);

my @results;

@ranges = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @ranges;

my $theRange = shift @ranges;
for my $range (@ranges) {
if ($theRange->[1] < $range->[0]) {
push @results, $theRange;
$theRange = $range;
} elsif ($theRange->[1] < $range->[1]) {
$theRange->[1] = $range->[1];
}
}

push @results, $theRange;

for my $range (@results) {
print "$range->[0] $range->[1]\n";
}
    • good
    • 0
この回答へのお礼

なるほど、二次元配列を使う手があるのは気がつきませんでした。
早速のご回答ありがとうございます。

ご参考の意見を基に早速試してみます。
取り急ぎ御礼まで

お礼日時:2007/12/18 22:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

今、見られている記事はコレ!

おしトピ編集部からのゆる~い質問を出題中

お題をもっとみる


このカテゴリの人気Q&Aランキング

おすすめ情報

カテゴリ