переупорядочить сортировку алфавита в Perl - PullRequest
3 голосов
/ 02 октября 2011

Я пытаюсь исправить сортировку по армянскому алфавиту, потому что все стандартные инструменты Unix и языки программирования сортируют буквы и слова в результате только для одного из 2 основных диалектов (западного).

Перевести это в техническую задачу - переупорядочить один из символов " ւ ", поместить его в другое место среди букв, скажем, сделать его последним символом, чтобы слова были упорядочены правильно на заказ диалект (восточный). Лингвистически говоря на восточном диалекте, этот символ " ւ " не написан "автономно", а является частью буквы, которая написана двумя символами " ու ". Текущая сортировка помещает букву " ու " за 2-буквенными конструкциями "ոք" или "ոփ".

По сути, это должно быть полностью похоже, если вы хотите сделать e. г. буква "v" будет на месте буквы "z" в латинском алфавите.

Я пытаюсь использовать что-то вроде

#!/usr/bin/perl -w
use strict;

my (@sortd, @unsortd, $char_u, $char_x);
#@unsortd = qw(աբասի ապուշ ապրուստ թուր թովիչ թոշակ թոք);
@unsortd = qw(ու ոց ոք ոփ);

@sortd = sort {
  $char_u = "ւ";
  $char_x = split(//, @unsortd);
  if ($char_u gt $char_x) {
    1;
  } else {
    return $a cmp $b;
  } 
} @unsortd;

print "@sortd\n";

но это не масштабируется для целых слов, исправлены только 2 буквенные формы.

ОБНОВЛЕНИЕ: мне удалось решить эту проблему с помощью функции tr для сопоставления букв цифрам, как показано в Perlmonks

Ответы [ 2 ]

12 голосов
/ 02 октября 2011

Вы должны взглянуть на модуль Unicode :: Collate :: Locale , если вы еще этого не сделали.

use Unicode::Collate::Locale;

my $collator = Unicode::Collate::Locale->new(locale => "hy");
@sortd = $collator->sort(@unsortd);
print join("\n", @sortd, '');

Это печатает:

ու
ոց
ոք
ոփ

(Я не уверен, что это ожидаемый вывод, но этот модуль и Unicode::Collate содержат достаточно много информации, возможно, было бы проще создать пользовательское сопоставление для ваших нужд на основе этого, а не накатывать свой собственный.)

0 голосов
/ 03 октября 2011

Для стандартных алфавитов Unicode::Collate::Locale в соответствии с предложением @mat должно быть первым выбором.

С другой стороны, если у вас очень специфические потребности, «index» можно использовать следующим образом. Чтобы отсортировать отдельные символы (обратите внимание, что пропущенные символы будут первыми):

my $alphabet_A = "acb";
sub by_A {index($alphabet_A,$a) <=> index($alphabet_A,$b)};

...

my @sorted = sort by_A @unsorted;

Для слов можно включить цикл в определение by_A. Чтобы следующее работало, определите функцию min () и настройте регистр слов различной длины:

sub by_A {
    $flag=0;
    foreach my $i (0..min(length($a),length($b))-1) { 
        return ($flag) if ($flag);
        $flag = ($flag or 
                 index($alphabet_A,substr($a,$i,1)) <=> index($alphabet_A,substr($b,$i,1)));
    }
    return $flag;
}
...