【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

こんばんわ。ソートの処理で行き詰ってしまいました…

(@allには正規表現で一致したデータを全て読み込んであります。)
foreach (@all){
($filename,$title,$sentence,)= split(/,/,$_);
$score = ..... #スコアを求める

この後@allを$scoreの値が大きい順にソートし、@sorted_listを作成したいのですが、この後どの様なコードを書けば良いのでしょうか?

自分で言うのもなんですがあまり上手く説明できませんでした…
わかりにくい説明ですがよろしくお願いします。

A 回答 (5件)

my @sorted_list = map {$_->[1]}


sort {$a->[0] <=> $b->[0]}
map {
my ($filename, $title, $sentence) = split /,/, $_;
my $score = $sentence * 100;
[$score, $_];
} @all;
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

まずは教えていただいたコードを解析することから始めたいと思います。

ありがとうございました

お礼日時:2006/01/09 23:27

すいません。

一つ前の私の回答は $score の計算まで勝手にやってますが、その辺は違いますので見ないで下さい。
    • good
    • 0

>ソートの基本は理解しているのですが、


>スコアを foreach内で算出しているので
>ご回答してくださった方法では無理みたいです^^;
現方法では、スコアを取っておいていないようですが・・
あとでスコアの大小を使って@allをソートするためには、@allの各行に付け加えなければいけません。

スコアを求めることを別にやったからといって、
ソートの中で一時的に求めたらいけないということはありません。
foreach の中で、@allが変化していないのであれば、
その後で、#1の方法でソートしても何の問題もありません。

my を使って一時的な変数を使っているので、外部に影響することもありません。

>スコアの算出方法は単純な処理で、ソートに関るような処理はしていません。
スコアの大小でソートをするわけですから、当然、ソートに関わっております。
ソートでスコアの大小を比較する処置が必要です。
    • good
    • 0
この回答へのお礼

スコアを算出している時点でソートに関ってますよね^^;

現時点では問題は解決していませんが、あと少しで問題を自己解決できそうです。
(もしかしたらもう一度お世話になるかもしれませんが・・・)

ありがとうございました。

お礼日時:2006/01/09 23:24

シュワルツ変換を使ってみては。

こんな感じ;
my @scored_list;
for ( @all ){
( $filename, $title, $sentence ) = split( /,/, $_ );
$score = ..... #スコアを求める
push @scored_list, [ [$filename, $title, $sentence], $score ];
]
my @sorted_list = map { $_->[0] } sort { $a->[1] <=> $b->[1] } @scored_list;

@sorted_listに、$filenameと$title、$sentenceを組とする配列のリファレンスが、ソートされて格納されます。
$scoreも保持したいとか、@allと同じ形式でデータを保持したい場合は、@scored_listへの格納法とソート比較式を適宜変更してください。

その他、perlfaq4とかに複雑なデータの取り扱い法が書かれてるので、一読されてみては。

参考URL:http://perldoc.jp/docs/perl/5.6.1/perlfaq4.pod
    • good
    • 0
この回答へのお礼

シュワルツ変換ですか・・・自分には難しそうですがトライしてみようと思います。

ありがとうございました。

お礼日時:2006/01/09 23:22

スコアを求める操作がわからないので一般的なsortについて書きますと


sub byscore {
#与えられた配列の中身2つを$a,$bとして大小比較した結果を返す関数
}
を作っておけば
@sorted_list = sort byscore @all;
で良いです。
例えば、
sub byscore {
#与えられた配列の中身2つを$a,$bとして大小比較した結果を返す関数
my ($filename,$title,$sentence)= split(/,/,$a);
my $scorea = ...#何らかの計算
($filename,$title,$sentence)= split(/,/,$b);
my $scoreb = ...#何らかの計算
$scoreb <=> $scorea;
}
というような感じになります。

実際に動作させて確かめていないので、おかしいところがあるかもしれませんが、そんな感じで・

この回答への補足

ご回答ありがとうございます。

ソートの基本は理解しているのですが、
スコアを foreach内で算出しているので
ご回答してくださった方法では無理みたいです^^;

@allをforeachで一行一行読み込んで
一行ごとのスコアを算出しています。

スコアの算出方法は単純な処理で、ソートに関るような処理はしていません。

もし宜しければ再度アドバイスをお願いしますm(_ _)m

補足日時:2006/01/08 06:06
    • good
    • 0

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


おすすめ情報