2014-11-13 3 views
0

У меня есть этот сценарий, использовать хэш-таблицу:получить nbest пар ключ-значение хэш-таблицу в Perl

#!/usr/bin/env perl 

use strict; use warnings; 

my $hash = { 
     'cat' => { 
       "félin" => '0.500000', 
       'chat' => '0.600000', 
       'chatterie' => '0.300000' 
       'chien' => '0.01000' 
      }, 
     'rabbit' => { 
        'lapin' => '0.600000'      
       }, 
     'canteen' => { 
        "ménagère" => '0.400000', 
        'cantine' => '0.600000' 
       } 
     }; 

my $text = "I love my cat and my rabbit canteen !\n"; 

foreach my $word (split "\s+", $text) { 
    print $word; 
    exists $hash->{$word} 
     and print "[" . join(";", keys %{ $hash->{$word} }) . "]"; 
    print " "; 
} 

На данный момент, у меня есть выход:

I love my cat[chat;félin;chatterie;chien] and my rabbit[lapin] canteen[cantine;ménagère] ! 

мне нужно иметь nbest значение ключа в соответствии с частотами (хранится в моем хеше). Например, я хочу иметь 3 лучшие переводы в зависимости от частоты, как это:

I love my cat[chat;félin;chatterie] and my rabbit[lapin] canteen[cantine;ménagère] ! 

Как я могу изменить свой код, чтобы принимать во внимание частоту каждых значений, а также для печати значения nbest?

Благодарим за помощь.

+1

Сортировать ключи численно? – TLP

+0

Да, согласно информации хэша, естественно. Например, для первой записи: 1) чат 2) félin 3) chatterie 4) chien. Затем, в моем примере, я хочу получить 3best значения. –

ответ

0

Самый простой способ сделать это - написать подпрограмму, которая возвращает N наиболее часто используемых переводов для данного слова. Я написал best_n в нижеуказанной программе. Он использует rev_nsort_by от List::UtilsBy, чтобы сделать вид лаконично. Это не основной модуль, поэтому его необходимо установить.

Я также использовал исполняемую подстановку, чтобы изменить строку на месте.

use utf8; 
use strict; 
use warnings; 

use List::UtilsBy qw/ rev_nsort_by /; 

my $hash = { 
    'cat'  => { 
    'félin'  => '0.500000', 
    'chat'  => '0.600000', 
    'chatterie' => '0.300000', 
    'chien'  => '0.01000', 
    }, 
    'rabbit' => { 
    'lapin'  => '0.600000', 
    }, 
    'canteen' => { 
    'ménagère' => '0.400000', 
    'cantine' => '0.600000', 
    } 
}; 

my $text = "I love my cat and my rabbit canteen !\n"; 

$text =~ s{(\S+)}{ 
    $hash->{$1} ? sprintf '[%s]', join(';', best_n($1, 3)) : $1; 
}ge; 

print $text; 

sub best_n { 
    my ($word, $n) = @_; 
    my $item = $hash->{$word}; 
    my @xlate = rev_nsort_by { $item->{$_} } keys %$item; 
    $n = $n > @xlate ? $#xlate : $n - 1; 
    @xlate[0..$n]; 
} 

выход

I love my [chat;félin;chatterie] and my [lapin] [cantine;ménagère] ! 
+0

В этом примере вывод - '[chien; chatterie; félin]', но nbest в соответствии с частотами - '[chat; félin; chatterie]'. Возможно, есть что изменить, чтобы решить это в подпрограмме? –

+0

@chester: Глупая ошибка: я отсортировал слова в * увеличении * порядка частоты и занял первые три, которые поэтому являются * наименее частыми. Тот же модуль предоставляет 'rev_nsort_by', который сортирует * убывающий * порядок и исправляет проблему. – Borodin