2011-10-02 6 views
3

J'essaie de corriger le tri en alphabet arménien, car tous les outils et langages de programmation Unix standard trient les lettres et les mots pour un seul des deux principaux dialectes (occidentaux).tri alphabétique trier en Perl

Traduire cela en problème technique consiste à réorganiser l'un des caractères « ւ », de le mettre dans un endroit différent entre les lettres, disons pour en faire le dernier caractère de sorte que les mots sont commandés correctement pour l'ordre dialecte (oriental). Linguistiquement parlant en dialecte oriental, ce symbole "ւ" n'est pas écrit "standalone" mais fait partie d'une lettre écrite avec 2 caractères "" ". Le tri actuel met la lettre "" "derrière" ոք "ou" ոփ "les constructions de 2 lettres.

Fondamentalement, il devrait être totalement similaire si vous vouliez faire e. g. la lettre "v" est à la place de la lettre "z" en alphabet latin.

Je suis en train d'utiliser quelque chose comme

#!/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"; 

mais cela n'échelle pas des mots entiers, à seulement 2 formes de lettre sont fixés.

MISE À JOUR: J'ai pu résoudre ce en utilisant la fonction tr pour mapper des lettres aux chiffres comme indiqué dans Perlmonks

+3

Vous ne devez jamais trier du texte en utilisant des comparaisons de points de code; ça ne va jamais avoir raison. C'est pourquoi 'Unicode :: Collate' et' Unicode :: Collate' existent. – tchrist

+0

Ajoutez ':: Locale' au 2ème. – tchrist

Répondre

12

Vous devriez jeter un oeil sur le module Unicode::Collate::Locale si vous ne l'avez pas déjà fait.

use Unicode::Collate::Locale; 

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

Cette impression:

ու 
ոց 
ոք 
ոփ 

(je ne suis pas sûr que ce soit la sortie que vous attendez, mais ce module et Unicode::Collate a beaucoup d'informations, il pourrait être plus facile de créer un classement personnalisé pour vos besoins basé sur cela plutôt que de rouler le vôtre.)

+0

J'ai essayé avec Unicode: Assembler et utiliser: locale, mais c'est pareil. J'aurais besoin d'un code similaire qui met une lettre latine à la place de "z" dans l'ordre des mots. – Temujin

+1

@ user278192 Vous ne voulez pas 'utiliser locale' - pratiquement jamais !! Vous voulez 'Unicode :: Collate :: Locale', et vous spécifiez les paramètres régionaux arméniens dans le constructeur. – tchrist

-1

Pour les alphabets standard Unicode::Collate::Locale comme suggéré par @mat devrait être le premier choix. Par contre, si vous avez des besoins très spécifiques, `index 'peut être utilisé comme suit. Pour trier les caractères individuels (notez que les caractères manquants seraient d'abord):

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

... 

my @sorted = sort by_A @unsorted; 

Pour les mots, on peut inclure une boucle dans la définition de by_A. Pour que cela fonctionne, définissez la fonction min() et affinez le cas des mots de différentes longueurs:

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