2009-09-02 34 views
9

這是一個最佳實踐問題。太空船操作員何時在排序之外使用?

我只看到了在數字排序例程中使用的Perl飛船運算符(< =>)。但在其他情況下似乎很有用。我只是想不出實際的用途。

任何人都可以給我一個什麼時候可以在Perl排序之外使用的例子嗎?

+0

@ether:只有「運營商」標籤?我以爲你喜歡創建新的操作員標籤! – 2011-01-20 11:46:16

回答

7

我正在寫一個機器人喬的控制系統,想要去機器人瑪麗和充電她。他們沿着線上的整數點移動。喬從$ 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); 

這裏還有一個,從wikipedia:「如果兩個參數不能比較(例如其中一個是NaN),操作符返回undef。」即你可以一次確定兩個數字是否是一個數字,儘管個人而言我會選擇不太神祕的Scalar::Util :: looks_like_number。

+2

實際上,'undef'行爲會導致問題,因爲'undef'會導致Perl很可能死亡。但是我們可以做一個處理NaN的數字排序:'sub numeric {$ a <=> $ b //($ a == $ a) - ($ b == $ b)}'這會將NaN排序到開頭,具有至少不會死亡的積極效果。 – 2009-09-03 03:14:47

5

<=>運營商將是一個有用的binary search algorithm。大多數編程語言沒有一個運算符進行三方比較,因此每次迭代需要進行兩次比較。用<=>你可以做一個。

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 – 2009-09-03 13:55:13

+0

將這兩個比較從明確寫入的語句委派給預處理器的內部結構有什麼性能優勢? – 2009-09-03 15:38:15

+1

在字節碼級別有一個運算符,而不是兩個:'perl -MO = Terse -e「$ a <=> $ b」'這就是說,由於Perl是用C實現的(它沒有三路比較運算符) '<=>'必須作爲內部的兩個比較來實現。任何性能優勢都是擴展發生在C而不是Perl中。當然,最終的限制是處理器的指令集支持的,而不管運營商C具有什麼。 – 2009-09-03 17:26:40

相關問題