Задача, сделать поисковик чтобы оценивал похожесть, степень одинаковости
предложений и текста.
есть какой-то текст в переменнах $b,$o,$tw,$tb, загоняется все в массив. Для
отладки пишется подпрограмма rrand(), которая переставляет случаным образом
элементы массива. Далее идет цикл, подсчитывающий частоты одинаковых слов в
переменных и заносящий эти частоты в хеш хешей.
Регулярное выражение while
$m[$i]=~m!((\w[\w-]*){4,30})!g; вырезает по
одному слову через пробел, причем ширина слова не менее 4 букв и не более
30.
В силу действия модификатора g работает цикл, заполняющий хэш хешей.
В хеше хешей 1(т.к.
нуумерация элементов массива была случаный образом изменена, то удобно
обращаться через номер массива) содержатся предположим для переменной $b такие данные:
т.е. слово африка по частоте употребления в три раза больше в файле, что
дает ему большие шансы вылезти в список перых результатов.
Далее следуют
слова будет и завтра, которые так-же играют немаловажную роль в поднятии
ссылки наверх из результатов поискового запроса. Далее в цикле объявляется
хеш(задача была сделать, а не память сэкономить), который будет выводить
результаты запроса.
Далее идет цикл:
запрашиваем численное название хеша в переменную $r, считываем с её помощью
хеши хешей. Здесь функцией exists реализован поиск общих ключей в двух
хешах: в хеше, поступающем на ввод, и текущем по шагу цикла хеше хешей.
Если информация содержится в начальном втором хеше %vr, то запрашиваем её
$vr{$r}. Строчка $u++ отвечает за количество вхождений всех слов, заданных в
запросе, в искомую строку(файл). Допустим на входе фраза "будет африка
завтра", если хотя бы одно слово из этой фразы совпало со словом в очередной
строке(ведь изначально строка была побита на частотный хеш) то локальная переменная
$u
увеличит свое значение на единичку. Если два слова в строке и в запросе
одинаковы, то $u=2, если три - $u=3 и так далее, слов в запросе может быть любое
количество. Далее идет строчка
которая заносит частоты слов(3,1,1 как было выше в примере) в текущей
строке. Дальше идет сама exists и после неё разбираемся с весом
повторяющихся слов и весом полных совпадений. Т.е. должно быть так, чтобы
полное совпадение фразы имело большее значение, нежели чем неполное
совпадение + пара повторов. Но функция федет себя по хитрому, допустим,
если нужно найти специализированную информацию типа "Хеш хешей хешей хешей
хешей массивов", то вес повторений слов будет больше, т.е. вклад члена
$ee[0]-1(разница в единицах на случай непреднамеренного повтора) больше, чем
$u. В то-же время частота повторений может запросто
вывести наверх ссылку с словом, которому посвящен текст. Т.е. некий баланс
для фраз, повторений и одиночных слов.
#!/usr/bin/perl -w
use locale;
%oo=("будет"=>1, "африка"=>1, "завтра"=>1);
$b="африка африка будет завтра африка";
$o="африка будет урааа зачем африка";
$tw="африка небудет вчера будет завтра";
$tb="аляска аляска будет будет будет сегодня";
@m=($b, $o, $tb, $tw); rrand(\@m);
print join "\n", @m,"\n";
for $i(0 .. $#m){
$h{$i}{$1}++ while $m[$i]=~m!((\w[\w-]*){4,30})!g;
$vr{$i}=$m[$i];
}
for $r(keys %h){print "\n";
my (@ee, $u, $trr);
for $n(keys %{$h{$r}}){
do{
$t = join " " => $vr{$r};
$u+=1;
push @ee => $h{$r}{$n};
} if exists $oo{$n};
}
print "$t ",$u + $ee[0]-1,"\n";
}
sub rrand{
my $m = shift; my $i;
for($i=@$m; --$i;){
my $j = int rand($i+1);
next if $i==$j;
@$m[$i,$j] = @$m[$j,$i]
}
}
$b = "африка африка будет завтра африка";
$h{1}=(
"африка" => 3,
"будет" => 1,
"завтра" => 1
);
for $r(keys %h){print "\n";
my (@ee, $u, $trr);
for $n(keys %{$h{$r}}){
do{
$t = join " " => $vr{$r};
$u++;
push @ee => $h{$r}{$n};
} if exists $oo{$n};
}
print "$t ",$u + $ee[0]-1,"\n";
}
push @ee => $h{$r}{$n};