2009-09-02 16 views
9

これはベストプラクティスの質問です。宇宙船オペレータはいつソート外で使用されますか?

数値ソートルーチンで使用されているPerl宇宙船オペレータ(< =>)のみを見てきました。しかし、それは他の状況で役に立つと思われます。私は実用的な使用を考えることはできません。

誰かがPerlソートの外で使用できる例を教えていただけますか?

+0

@ether:「演算子」タグのみ?私は新しいオペレータタグの作成が好きだと思った! –

答えて

7

私は、ロボットのジョーにロボットMaryに行き、彼女を充電したいコントロールシステムを書いています。それらはライン上の整数点に沿って移動する。ジョーは$ jで始まり、時間単位ごとにどの方向にも1メートル歩くことができます。メアリーは$ mのところにまだ立っていて、動くことはできません - 彼女は良い充電が必要です!制御プログラムは、次のようになります。

while ($m != $j) { 
    $j += ($m <=> $j); 
} 
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; 
} 

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

私は統計分析のためであると考えることができる一つの他の使用 - 値がセットの算術中央値より高いか低い場合は、値が繰り返し値のリストに対して実行されている場合は、あなたが言うことができます。

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つ、wikipediaから: "2つの引数を比較できない場合(たとえば、そのうちの1つがNaNの場合)、演算子はundefを返します。つまり、私は個人的に私はあまり秘密のScalar::Util :: look_like_numberに行くだろうが、2つの数字が同時に数字であるかどうかを判断することができます。

+2

実際には、 'undef'動作は問題を引き起こす可能性があります。これは、' undef'がソートするとPerlが死ぬ可能性が高いからです。しかし、NaNを扱う数値ソートを行うことができます: 'sub numeric {$ a <=> $ b //($ a == $ a) - ($ b == $ b)}'これはNaNを最初にソートします。少なくとも死ぬことはないという肯定的な効果があります。 –

5

<=>オペレータはbinary search algorithmのために有用であろう。ほとんどのプログラミング言語には、反復ごとに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; 
} 
+0

バイナリ検索を正しく*実装することがどれほど驚くほど難しいかを考えれば、私はもう一つの壊れた例を世界に貢献していないことを願っています。 :P –

+0

これら2つの比較を明示的に記述された文からプリプロセッサの内部に委譲することのパフォーマンス上のメリットは何ですか? –

+1

バイトコードレベルでは、2つではなく1つの演算子があります。 'Perl -MO = Terse -e" $ <=> $ b "PerlはC言語で実装されているので(3方向比較演算子はありません) '<=>'は内部で2つの比較として実装する必要があります。パフォーマンス上の利点は、展開がPerlではなくC言語で行われることです。もちろん、最終的には、Cの演算子に関係なく、プロセッサの命令セットがサポートするものが制限されます。 –

関連する問題