• ベストアンサー

Perlのソートについて

ハッシュを利用して今ソートできるプログラムを作成したのですが、 重複するデータは除外されてしまうようで、どうしたら除外されずに ソートできるかを教えていただきたいです。 <例> 文字 よみ  No      橋  はし  1      橋  はし  3      箸  はし  2 というデータがあったとして、今のプログラムを実行すると・・・ <結果> 箸  はし  2 キーがよみなので3番目のデータだけ残ります。キーを漢字に したとしても1番目のデータは残らないのですが、どうしてらよいのでしょうか。 <理想的な結果>      橋  はし  1      箸  はし  2      橋  はし  3 一番いいのが上のような結果で、Excelのソートのような感じで、第1キーはよみで第2キーはNoとかのソートはPerlでできないでしょうかね?? どなたか分かる方がいたら教えていただきたいです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

$form_file = "sort2.log"; $to_file = "sort2.txt"; open(F1, $form_file) || die "$form_file をオープンできません:$!\n"; open(F2, ">$to_file") || die "$to_file を作成できません:$!\n"; foreach(sort useSort <F1>){ print F2 $_; } close(F2); close(F1); sub useSort{ (split(/\t/,$a))[1] cmp (split(/\t/,$b))[1] || (split(/\t/,$a))[2] <=> (split(/\t/,$b))[2] } 多分こんな感じになるんじゃないですかね。 <F1>の中身が下のようになっていたらのお話です。 橋\tはし\t2 橋\tはし\t1 橋\tはし\t3

Chiaki---
質問者

補足

返事遅くなって申し訳ありません。 プログラムやってみました。上手くソートができていました。 しかし、プログラムがいまいち分からないので、今後の勉強の為にも もうちょっと詳しく教えていただきたいです。 foreach(sort useSort <F1>){ print F2 $_; } close(F2); close(F1); sub useSort{ (split(/\t/,$a))[1] cmp (split(/\t/,$b))[1] || (split(/\t/,$a))[2] <=> (split(/\t/,$b))[2] } の意味を教えていただきたいです。よろしくお願いします。

その他の回答 (4)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#3>Noについての Noは、どのように決定するのでしょうか? 置換前のファイルに手入力で追加するのですか? 現在のような $mozi{$yomi} = "$mein"; では、同じ読みが1つしか保存されません $mozi{'はし'}=['橋','箸','端']; みたいな構造、(位置がNoをあらわす)とするか $mozi{'はし'}=[['橋',1],['箸',2],['端',3]]; のような構造がいいかもしれません。 ところで、例のように 橋 はし 1 橋 はし 3 みたいに同じ文字、同じ読みで違うNoが付くことはあるんですか

Chiaki---
質問者

補足

文字の保存の仕方がいけないのですね・・・。少し考えてみます。 ありがとうございます。 同じ文字でNoが違うバージョンはたくさんあるんですよね。 それがなかったら、簡単にできるんですが。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

ハッシュでどんな風にデータが格納されているんでしょうか? 「ソートできるプログラムを作成した」を補足で挙げられますか?

Chiaki---
質問者

補足

print"置換元のファイル名を指定ください:"; $form_file = <STDIN>; print"置換後のファイル名を指定してください:"; $to_file = <STDIN>; chomp($form_file, $to_file); open(F1, $form_file) || die "$form_file をオープンできません:$!\n"; open(F2, ">$to_file") || die "$to_file を作成できません:$!\n"; while ($line = <F1>) { chomp $line; ($mein, $yomi) = split (/\t/, $line); $mozi{$yomi} = "$mein"; } foreach $value (sort keys %mozi) { print F2 "$mozi{$value}\t$value\n"; } 作成してみたのが、これです。 まだNoについてのプログラムはわからないので作成できていませんが・・ できますかね??よろしくお願いします

回答No.2

#!/usr/local/bin/perl use strict; my @DATA = ( [ '橋', 'はし', 1 ], [ '橋', 'はし', 3 ], [ '箸', 'はし', 2 ], ); @DATA = sort { $a->[2] <=> $b->[2] } sort { $a->[1] cmp $b->[1] } @DATA; for (@DATA) { print $_->[0] . $_->[1] . $_->[2] . "\n"; } exit; 検証していませんので自信はないです:)

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 んっと……記述されているデータだけを考えると単純に「Noをキーにしてソート」で片付くと思うのですが。 もし「それじゃNG」なようであれば、もう少し細かく「ソート条件」を教えていただければ、多分返答できるかと思います。

関連するQ&A