9

Perl の宇宙船演算子 (<=>) が数値ソート ルーチンで使用されているのを見たことがあります。しかし、それは他の状況で役に立ちそうです。実用的な使い方しか思いつきません。

Perl ソート以外で使用できる例は何ですか?

これはベスト プラクティスの質問です。

4

3 に答える 3

7

私は、ロボット メアリーに行って彼女を充電したいロボット ジョーの制御システムを書いています。それらは線上の整数点に沿って移動します。Joe は $j から開始し、単位時間あたり任意の方向に 1 メートル歩くことができます。メアリーは $m でじっと立っていて、動けません。十分な充電が必要です! 制御プログラムは次のようになります。

while ($m != $j) {
    $j += ($m <=> $j);
}
于 2009-09-02T23:09:20.133 に答える
5

<=>演算子は、二分探索アルゴリズムに役立ちます。ほとんどのプログラミング言語には、反復ごとに2つの比較を行う必要がある3者間比較を行う演算子がありません。あなたと一緒<=>に1つだけを行うことができます。

sub binary_search {
    my $value = shift;
    my $array = shift;
    my $low   = 0;
    my $high  = $#$array;

    while ($low <= $high) {
        my $mid = $low + int(($high - $low) / 2);

        given ($array->[$mid] <=> $value) {
            when (-1) { $low  = $mid + 1 }
            when ( 1) { $high = $mid - 1 }
            when ( 0) { return $mid      }
        }
    }

    return;
}
于 2009-09-03T02:21:17.713 に答える
2

どんな比較方法でも構いません。たとえば、複雑なオブジェクトを持つことができますが、それでも定義済みの「順序」があるため、比較関数を定義できます (便利ですが、並べ替えメソッド内で使用する必要はありません)。

package Foo;

# ... other stuff...

# Note: this is a class function, not a method
sub cmp
{
    my $object1 = shift;
    my $object2 = shift;

    my $compare1 = sprintf("%04d%04d%04d", $object1->{field1}, $object1->{field2}, $object1->{field3});
    my $compare2 = sprintf("%04d%04d%04d", $object2->{field1}, $object2->{field2}, $object2->{field3});
    return $compare1 <=> $compare2;
}

もちろん、これは完全に不自然な例です。しかし、私の会社のソース コードでは、日付と時刻の情報を保持するために使用されるオブジェクトを比較するために、ほぼ正確に上記を見つけました。

私が考えることができるもう 1 つの用途は、統計分析です。値が値のリストに対して繰り返し実行される場合、値がセットの算術中央値よりも高いか低いかがわかります。

use List::Util qw(sum);
# $result will be
#   -1 if value is lower than the median of @setOfValues,
#    1 if value is higher than the median of @setOfValues,
#    0 if value is equal to the median
my $result = sum(map { $value <=> $_ } @setOfValues);

ウィキペディアからもう 1 つ: 「2 つの引数を比較できない場合 (たとえば、そのうちの 1 つが NaN)、演算子は undef を返します。」つまり、2 つの数値が数値であるかどうかを一度に判断できますが、個人的にはわかりにくいScalar::Util ::looks_like_number を選択します。

于 2009-09-02T23:01:54.690 に答える