Perl を使い始めて数年になり、雑誌の隅っこに載る程度のフリーソフトなら作るようにもなりましたが、未だにソート関数の内部構造がさっぱり分かりません(^_^;

 Perl の解説本も数冊、ホームページに至っては十数ほども有名と言われているところを回ってみましたが、ほとんどの Perl ユーザーがソート関数の使い方を丸覚えにしているようで、的を得ない解説しか載ってません。

 そこで質問ですが、$a と $b には、いったい「何が」「どういうタイミングで」入ってきているのでしょうか?(配列の値が比較されるときに呼び出される、ということは分かりますが)
 当たり前に考えれば、ソート関数というものは全てをユーザーに任せて関数を書かせるか、でなければフルオートで全てやってくれるソート関数を用意するか、どちらか1方しかないはずです。

 なのに、Perl のソート関数は途中部分だけユーザーに書かせるという器用なことをやってます。
 これはいったいどういう構造になっているのでしょう?

このQ&Aに関連する最新のQ&A

A 回答 (1件)

> 当たり前に考えれば、ソート関数というものは全てをユーザーに任せて関数を書かせるか、でなければフルオートで全てやってく


> れるソート関数を用意するか、どちらか1方しかないはずです。

そのふたつ以外に、もうひとつ当たり前があります。

ソートは、要素の大小比較をして、逆転していれば要素を入れ替える、という
ことをやるわけですが、「要素の大小比較」というのは、ときと場合によって
いろいろ変わります。

というわけで、その変わるところ、つまり「やり方」をソート関数に渡すという
方法があります。

これは perl に限ったことでは無いのですが、(もう、古い言い方なんですが)
コールバック処理と言います。

ある処理(この場合は大小比較)を呼び出す側で用意して、何らかの処理(ソート)
から呼び出す、つまり、呼び戻すように見えることから、この名前がついています。


処理自体を指定する手段がある言語の標準的なソートは、大体こういう形式
になってます。私が知っているところだと C/C++、ruby なんかがそうです。
    • good
    • 0
この回答へのお礼

 ありがとうございます。

 もしかして、比較結果で入れ替えるかどうか判断してるだけなんでしょうか(笑)
 だとしたら俺は何を悩んでいたのだろう(^_^;

お礼日時:2001/10/10 15:53

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

このQ&Aと関連する良く見られている質問

Q[perl] $xxx == 1 or $xxx == 5 or $xxx == 11 などと書くが面倒です

タイトルの通りです

if文などで長々と書くのが面倒なのですが何かいい方法はないのでしょうか?
以前はif($xxx =~ /^1$|^5$|^11$/)などと書いていたのですが、正規表現を使うと処理が遅いんですね

なるべく処理が軽くて簡潔な書き方がありましたら紹介してください

Aベストアンサー

配列なら
my @array = (1, 5, 11);
if (grep {$_ == $xxx } @array) { ... }
とかかな. ハッシュなら
my %valid = ( 1 => 1, 5 => 1, 11 => 1 );
if ($valid{$xxx}) { ... }
のような感じ (「ハッシュを使った重複チェック」のバリエーション).
あ,
if ($xxx == (1 or 5 or 11)) { ... }
のような形は, (そのままじゃないけど) Perl6 でサポートされる予定になっています. いつのことかは知りませんが.

Qperlスクリプト s/^\s+//;  s/\s+$//;  return wantarray ? @out : $out[0]; について

自作の掲示板を作ろうと思い、perlの勉強をしている者です。人様の作ったスクリプトを解析しています。以下のスクリプトはライブラリに記述されていたものです。


sub tttt {
my @out = @_;
for (@out) {
s/^\s+//;
s/\s+$//;
}
return wantarray ? @out : $out[0];


このスクリプトなんですが、 s/^\s+//; の部分の「+」と s/\s+$//; の部分の「+$」、 また「return wantarray~」 の三つの部分のスクリプトが、どういった働きをしているの分かりません。専門書やウェブ上のリファレンスも色々調べたのですが・・。

分かる方いらっしゃいましたらご教授下さると幸いです。よろしくお願いします。

Aベストアンサー

まず前2つの「+」は,正規表現における,「直前の表現を一回以上繰り返し」をあらわします.
「\s」は空白文字一文字を表す正規表現ですので,「\s+」は,「一文字以上の空白文字」になります.
次に,最初の「^」と2番目の「$」は,その正規表現がどこに現れるかを示す記号です.それぞれ,先頭と最後尾にあることを示します.
したがって,「^\s+」は,「最初に空白が一文字以上ある文字列」に,
「\s+$」は「行末に空白が一文字以上ある文字列」にヒットします.
置換構文sはご存知なんですかね.すなわち,この2文で,行の最初と最後の空白を消しているんです.

次に, wantarray ですが,
http://www2u.biglobe.ne.jp/~MAS/perl/ref/wantarray.html
によると,このサブルーチンttttを呼び出すときに,何を返り値にしているかで真偽が決まる関数です.
呼び出す時に配列を希望していたら @out 全体を,変数を希望していたら $out[0]だけを返します.

QPerlでsub a($)のように$をつける効果は? 引数の細かい仕様について

よくPerlの書籍にsub a($$)のように$をつけるのは、
その関数の引数を明示するのに記述面で優れていると重いますが、他に何か効果や果たす役割はあるのでしょうか?
また sub a(){と sub a{の記述の仕方で動作が異なることはあるのでしょうか?

Aベストアンサー

> sub a(){と sub a{の記述の仕方で動作が異なることはあるのでしょうか?

例えば、

% cat a.pl
use strict;
sub a () {
print $_[0];
}
a( 1 );
% perl -c a.pl
Too many arguments for main::a at a.pl line 5, near "1 )"
a.pl had compilation errors.
% cat b.pl
use strict;
sub a {
print $_[0];
}
a( 1 );
% perl -c b.pl
b.pl syntax OK
%

――とか。

参考URL:http://www.kt.rim.or.jp/~kbk/perl5.005/perlsub.html

Q$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );がよく

$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );

というスクリプトがあったのですが、

$wfurikae = 1 の後に;もいれずifがきています。

違和感があります。

どのような意味になるのでしょうか。

宜しくお願い致します。

Aベストアンサー

そのまんまだと思いますよ。
if 以下の条件が真の時 $wfurikae = 1となります。
Perlはいろいろな書き方ができますので、こういう書き方もありです。
英語の文法の並びにする書き方です。

QPrel正規表現で'$1$'.$saltのあたりが理解できない。

小生Perlを勉強中です。
Perl Codeに以下のようなパスワード暗号処理のサブルーチンが
ありましたが、読めません。教えて下さい。

sub encrypt{
local($inpw)=$_[0];
local(@SALT,$salt,$encrypt);

@SALT=('a'..'z','A'..'Z','0'..'9','.','\');
srand;
$salt=$SALT[int(rand(@SALT)).$SALT[int(rand(@SALT))];
$encrypt=crypt($inpw,$salt)||crypt($inpw,'$1$'.$salt);
return $encrypt;
}

とあります。
特に、下から3行目の($inpw,'$1$'.$salt)が
理解できません。
解説していただければ幸いです。

Aベストアンサー

過去に同様の質問がありました。ctpsysさんの疑問にすべて答えられるかどうかわかりませんが、すくなくとも
>下から3行目の($inpw,'$1$'.$salt)が理解できません
というご質問に対しては参考になるかと思います。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,


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

おすすめ情報