Вторичный порядок в куче:: Simple

Как определить вторичный порядок для интерфейса Heap::Simple в Perl?


person syker    schedule 30.06.2010    source источник


Ответы (2)


В документации указано, что конструктор использует ссылку на код для определения порядка, поэтому вы можете указать любой метод сортировки, который вам нравится:

my $heap = Heap::Simple->new(order => \&sort_method);

Каждый раз, когда необходимо сравнить два ключа, данная ссылка на код будет вызываться следующим образом: $less = $code_reference->($key1, $key2);

Это должно возвращать истинное значение, если $key1 меньше, чем $key2, и ложное значение в противном случае. $code_reference должен подразумевать отношение общего порядка, поэтому он должен быть транзитивным.

Под «вторичным порядком» я предполагаю, что вы имеете в виду, что второе сравнение используется, если первое показывает, что значения равны. Допустим, первое сравнение — это значения, найденные с помощью метода «метод1», а второе сравнение — значения, полученные с помощью «метода2». Итак, если по методу1 значения отличаются, верните этот результат и в противном случае вернитесь к методу2:

sub sort_method
{
    my ($val1, $val2) = @_;

    my $result = ($val1->method1 <=> $val2->method1)
                          ||
                 ($val1->method2 <=> $val2->method2);

    return 1 if $result == -1;
}

Если метод1 и метод2 возвращают строки вместо числовых значений, просто используйте оператор cmp вместо <=>. Вы можете использовать все, что угодно, пока оператор возвращает правильные значения. Большинство функций сортировки используют значения -1, 0 и 1, чтобы указать, является ли значение1 меньше, равно или больше значения2, но этот модуль предпочитает, чтобы 1 означало значение1 ‹ значение2, поэтому после сбора значений -1, 0, 1 результат, затем возвращается 1, если результат равен -1 (где значение1 меньше значения2).

person Ether    schedule 30.06.2010
comment
Должен ли я определять атрибут elements при построении кучи? Я точно знаю, что каждый из моих элементов представляет собой массив определенного размера (и на самом деле метод сортировки рассматривает два значения в этом массиве). Например: my $heap = Heap::Simple-›new(order =› \&sort_method, elements =› Array); - person syker; 30.06.2010
comment
Я исправил неработающую ссылку на документацию. - person Zaid; 30.06.2010
comment
У меня возникли проблемы с попыткой написать функцию сравнения на основе элементов массива. Может ли кто-нибудь указать мне ресурсы по такой теме? - person syker; 30.06.2010
comment
Почему нельзя было использовать $b и $a вместо $val2 и $val1 соответственно? - person syker; 30.06.2010
comment
@syker: $a и $b рассматриваются как глобальные переменные в Perl, поэтому лучше избегать их вне кодовых ссылок, передаваемых в функцию sort. - person Ether; 30.06.2010

Прежде всего, вы пишете функцию, которая принимает два объекта, которые вы хотите поместить в кучу, и возвращает значение true, если первый меньше второго, и false в противном случае.

Затем укажите это как coderef в Heap::Simple.

Пример из документации Heap::Simple выглядит следующим образом:

use Heap::Simple;

sub more { return $_[0] > $_[1] }

my $heap = Heap::Simple->new(order => \&more);
$heap->insert(8, 3, 14, -1, 3);
print $heap->extract_top, " " for 1..$heap->count;
print "\n";
# Will print: 14 8 3 3 -1
person Anon.    schedule 30.06.2010