Короче я сделал вот это чудовище:
PHP:
function search_words($str1, $str2) {
if ($str1 == $str2) return 100;
$str1 = trim(strtoupper($str1));
$parr = array(1=>100,2=>40,3=>60,4=>70,5=>75,6=>80,7=>80,8=>80,9=>80,10=>80,11=>80,12=>90,13=>90,14=>90,15=>90,16=>90,17=>90,18=>90,19=>90,20=>90);
$words1 = preg_split("/[^\x2d\x30-\x39\x41-\x5a\x61-\x7a\xc0-\xff\xb8\xa8']+/",$str1,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$words2 = preg_split("/[^\x2d\x30-\x39\x41-\x5a\x61-\x7a\xc0-\xff\xb8\xa8']+/",strtoupper($str2),-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$_str1 = implode(" ",$words1);
$_str2 = implode(" ",$words2);
$count1 = count($words1);
$count2 = count($words2);
$karr = array();
$strc = array();
for ($i=0;$i<$count1;$i++) {
$len = strlen($words1[$i]);
for ($j=0;$j<$count2;$j++) {
similar_text($words1[$i], $words2[$j], &$p);
if (intval($p)>$parr[$len]) {
if (!isset($karr[$j])) {
$karr[$j] = 1;
$strc[] = $words2[$j];
}
}
}
}
$str3 = implode(" ",$strc);
$ost = ($count1 < $count2) ? (($count2-count($strc))*0.1) : 0;
if ($count1 == $count2) $ost += 0.1;
similar_text($str1, $str3, &$proc);
return $proc-$ost;
}
Впринципе работает как надо, а имеенно запрос "Михаил Боярский" выводит:
100% - Михаил Боярский
100% - Михаил Боярский
99.9% - Боярский Михаил
99.9% - Боярский Михаил
99.7% - Татьяна Буланова И Михаил Боярский
69.4652173913% - М. Боярский
69.4652173913% - М. Боярский
69.4652173913% - М. Боярский
69.4652173913% - М. Боярский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Шуфутинский
57.0428571429% - Михаил Круг
57.0428571429% - Михаил Круг
Запрос "М. Боярский" дает более интересную картину:
100% - М. Боярский
100% - М. Боярский
100% - М. Боярский
100% - М. Боярский
84.1105263158% - Боярский Михаил
84.1105263158% - Боярский Михаил
84.1105263158% - Михаил Боярский
84.1105263158% - Михаил Боярский
83.8105263158% - Татьяна Буланова И Михаил Боярский
Получается, что чем меньше слов в запросе, тем лучше поиск.
Вот тока проблема в том, что сравнивать (искать повторы) такой функцией базу из 20 тысяч записей очень проблемно, в плане времени и затрате ресурсов.
Пробывал на mysql это делать, там глючно получается, так как mysql неможет определить ошибки в слове, и невидит слова "БОярский" и "БАярский" например.
А мне все это надо, для того чтобы искать одинаковых исполнителей и исправлять написание имени на правильные значения, т.е есть база большая с именами в правильной расстановке, по которой я и собираюсь править всю базу.
Можете ченить подсказать, как можно мои задачи решить более гуманно?
-~{}~ 11.11.07 05:45:
Кстати, а может есть где уже готовые решения для сравнения записей и поиска повторов?
Меня интересуют только 2 задачи:
1) Сравнение всех слов запроса, обычно это Имя и Фамилия, бывает имя указано только 1 буквой.
2) Сравнение слов с ошибками, т.к множество записей попадаются с неправильным написанием слова.