Когда оператор космического корабля используется вне сортировки?

StackOverflow https://stackoverflow.com/questions/1370511

Вопрос

Это вопрос из лучших практик.

Я видел только оператора космического корабля Perl (<=>) используется в процедурах числовой сортировки.Но это кажется полезным в других ситуациях.Я просто не могу придумать практического применения.

Кто-нибудь может привести мне пример того, когда это можно было бы использовать вне сортировки Perl?

Это было полезно?

Решение

Я пишу систему управления для робота Джо, который хочет пойти к роботу Мэри и подзарядить ее.Они перемещаются вдоль целых точек на прямой.Джо начинает с $ j и может пройти 1 метр в любом направлении за единицу времени.Мэри стоит неподвижно на отметке в миллион долларов и не может пошевелиться - ей нужна хорошая подзарядка!Управляющая программа будет выглядеть следующим образом:

while ($m != $j) {
    $j += ($m <=> $j);
}

Другие советы

В <=> оператор был бы полезен для алгоритм бинарного поиска.В большинстве языков программирования нет оператора, который выполняет трехстороннее сравнение, что делает необходимым выполнение двух сравнений за итерацию.С <=> вы можете сделать только одно.

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;
}

В любом виде метода сравнения.Например, у вас может быть сложный объект, но он все еще имеет определенный "порядок", поэтому вы могли бы определить для него функцию сравнения (чего вы не делаете иметь использовать внутри метода сортировки, хотя это было бы удобно):

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);

Вот еще один, из википедия:"Если два аргумента не могут быть сопоставлены (напримеродин из них - NaN), оператор возвращает undef". т.е.вы можете определить, являются ли два числа числом a сразу, хотя лично я бы выбрал менее загадочное Скалярный::Util::похожий номер.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top