строка perl :: Приблизительно для массивов

#arrays #perl #cpan #fuzzy-comparison

#массивы #perl #cpan #нечеткое сравнение

Вопрос:

Я использую String::Approx, чтобы найти наиболее похожее соответствие для массива из двух элементов из списка других. Я был приятно удивлен, обнаружив, что вы можете использовать amatch() для сравнения массива с массивом, хотя эта функция не документирована; Я был готов написать свою собственную функцию для этого. Я был еще более удивлен, увидев, что порядок элементов не имеет значения. Но, даже несмотря на то, что amatch() работает безупречно, у меня возникают трудности с adist() . Рассмотрим следующую программу:

 #! /usr/bin/perl

use String::Approx qw (amatch adist);

@matches = qw();
%matchhash = qw();
@matchstr = qw(cat dog);
@poss = (['rat', 'hog'],
     ['gnat', 'frog'],
     ['giraffe', 'elephant'],
     ['dig', 'bat'],
     ['catatonic', 'doggone'],
     ['care', 'dog'],
     ['care', 'ding'],
     ['hawk', 'shark']);

@matches = grep { amatch (@matchstr, @$_) } @poss;

foreach $k (@matches)
{
    $dist = adist( @matchstr, @$k );
    print "@matchstr has a difference from @$k of $dist n";
}
  

И вот что это выводит:

 cat dog has a difference from rat hog of 3
cat dog has a difference from gnat frog of 3
cat dog has a difference from dig bat of 3 
cat dog has a difference from catatonic doggone of 3
cat dog has a difference from care dog of 3
cat dog has a difference from care ding of 3
  

Итак, похоже, что он выбирает правильные ответы (он проигнорировал ['giraffe', 'elephant'] и ['hawk', 'shark'] ), но он не может сказать мне расстояние. Конечная цель — упорядочить совпадения по расстоянию и выбрать наиболее похожее @matchstr . amatch() Действительно ли работает так, как я думаю, или я просто использую слишком простой ввод? Почему не amatch() работает?

Ответ №1:

Вы не можете передать массив в качестве первого аргумента amatch или adist и заставить его работать так, как вы ожидаете.

Массивы распаковываются в списки, поэтому amatch видит что-то вроде amatch( 'cat', 'dog', 'rat', 'hog' ) , что, конечно, не то, что вы предполагали.

Вам нужно будет создать новые версии amatch и adist, которые поддерживают ссылку на массив в качестве первого аргумента. Затем вам нужно будет вызвать вспомогательные модули как my_amatch(@matchstr, @$_)

Комментарии:

1. Хорошо, я понимаю ваш ответ, но я все еще не понимаю, почему amatch (), похоже, работает правильно.

Ответ №2:

amatch не «делает то, что вы думаете».

Если вы измените qw (cat dog) на qw (cat zzz), вы получите те же результаты.

Затем, если вы измените «hawk», «shark» на «hawk», «zzz», вы все равно получите те же результаты.

Похоже, что он выполняет сравнение только с «cat».