Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как мне сравнить упакованные значения в Perl?

Автор вопроса: PP.Ответов: 3

Я хочу использовать функцию Perl pack() для кодирования некоторых данных. Затем я хочу сравнить свою упакованную структуру с другой упакованной структурой. Я хочу, чтобы это сравнение было по байтовым значениям этой упакованной структуры.

Согласно документации, cmp использует текущую локаль для определения способа сравнения строк. Но я не хочу, чтобы к сравнению применялся какой-либо интеллект. Я хочу все, что ближе всего к memcmp(). Очевидно, я не могу использовать <=> для сравнения упакованных объектов, поскольку они не являются числами.

Как лучше всего сравнивать упакованные строки в Perl?

Примечание: я читал эту статью об эффективной сортировке в Perl, в которой отмечается, что простая Функция sort использует алгоритм, подобный memcmp, для сравнения структур. Мне интересно, как добиться такого сравнения без использования сортировки.

  • sort действительно отличное место для начала. Попытка создать собственную сортировку-замену, вероятно, не сработает так хорошо, как хотелось бы, поскольку сортировка в Perl годами доводилась до совершенства. Ссылка на эффективную сортировку, которую вы дали, на самом деле включает инструкции о том, как использовать упакованные структуры данных для ускорения сортировки, что довольно умно, но сортировка должна занять много времени, прежде чем я посвятю себя ее поддержке. sarnold 20.07.2010
  • Вы хотите сравнение (т. е. меньше, больше или равно) или проверку на равенство "да" или "нет"? Greg Bacon 20.07.2010
  • @gbacon: я хочу что-то, что я могу заказать, так что меньше, больше, равно. PP. 20.07.2010
  • perldoc.perl.org/perllocale.html#The-use-locale- pragma - говорит, что по умолчанию локаль игнорируется. Где вы прочитали, что Perl использует текущую локаль? В документах для cmp также говорится, что языковой стандарт используется "только в том случае, если действует языковой стандарт". Если действует "использовать локаль", используйте "без локали", как предлагается ниже. runrig 20.07.2010
  • @runrig спасибо за исправление опечатки. PP. 21.07.2010

packcompareperl

Ответы

Ответ 1 · рейтинг 5 · Greg Bacon

Отключите учет локали для блока и используйте cmp как обычно:

sub mycmp {
  no locale;
  $_[0] cmp $_[1];
}

Документация perlop содержит

lt, le, ge, gt и cmp используют порядок сопоставления (сортировки), указанный в текущей локали, если действует use locale. См. perllocale.

а затем в perllocale

Поведение по умолчанию восстанавливается с помощью прагмы no locale или по достижении конца блока, содержащего use locale.

Например, бег

my($one,$two) = map pack("N", $_) => 1, 2;
say mycmp($one, $two);
say mycmp($two, $one);

выходы

-1
1

Ответ 2 · рейтинг 4 · daxim

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

unpack('H*', $first) cmp unpack('H*', $second)

Ответ 3 · deepakg

Здесь мысли вслух - помогут ли побитовые операторы? Подобно тому, как выполнение xor для двух идентичных строк даст битовую строку, в которой все установлено на 0.

http://perldoc.perl.org/perlop.html#Bitwise-String-Operators

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы