宇宙船のオペレーターはソート以外でいつ使用されますか?
-
21-09-2019 - |
質問
これはベストプラクティスの質問です。
Perl の宇宙船演算子 (<=>) が数値ソート ルーチンで使用されているのを見たことがあります。しかし、他の状況でも役立つようです。ただ実用的な使い方が思いつきません。
Perl ソート以外で使用できる例を誰か教えていただけますか?
解決
私はロボットメアリーに行き、彼女を充電したいロボットジョーのための制御システムを書いています。彼らはライン上の整数点に沿って移動します。ジョーは$ Jから始まり、単位時間あたりの任意の方向に1メートルを歩くことができます。メアリーは$メートルで静止して移動することはできません - 彼女は良い充電を必要としています!制御プログラムがそのようになります:
while ($m != $j) {
$j += ($m <=> $j);
}
他のヒント
は<=>
演算子はバイナリサーチアルゴリズムのに有用であろう。ほとんどのプログラミング言語は、反復ごとに2つの比較を行うためにそれが必要になり、三方比較を行う演算子を持っていません。 <=>
であなただけのいずれかを行うことができます。
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;
}
あらゆる種類の比較方法で。たとえば、複雑なオブジェクトがあっても「順序」が定義されている場合、それに対する比較関数を定義できます (これは実際には定義できません)。 持っている sort メソッド内で使用すると便利ですが):
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);
もう一つ、こちらから ウィキペディア:「2 つの引数を比較できない場合 (例:それらの 1 つは NaN)、演算子は undef を返します。」つまり2 つの数字が数字であるかどうかを一度に判断できますが、個人的には、より難解でない方を選びます。 スカラー::ユーティリティ::っぽい番号。