Как сравнить слова в тексте и поменять местами слова

jeka!

Просто Member
Как сравнить слова в тексте и поменять местами слова

Такая трабла, сравниваю тексты базы исполнителей через similar_text()
Например сравнение "Михаил Боярский" и "Боярский Михаил" дает 53% совпадения, хотя текст впринципе идентичный.
А если в слове хотябы 1 ошибочная буква, то уже 40%

Как можно переставить слова в тексте, в правильном порядке, чтобы потом их можно было сравнить similar_text()?

У меня ниче на ум неидет, кроме кучи операций, разбивки текста по словам и последующего сравнения каждого слова.
но это сделает поиск настолько проблемным, что врядли мне подойтет, база оч большая.
 

Pigmeich

Новичок
jeka!
А при чем тут similar? Это специфический алгоритм, который делался для английского языка и, значит, неслабо учитывает порядок слов.

Скорее всего тебе можно найти другое решение вроде explode по пробелу и array_reverse(). :)
 

jeka!

Просто Member
Да similar_text работает одинаково как с русским текстом так и с англ. всеравно 50%
Даж перевел в транслит чтобы проверить.
 

Pigmeich

Новичок
jeka!
Я не про кодировку, а про алгоритм.

В английском порядок слов меняет смысл предложения с повествовательного на вопросительный (есть и ещё похлеще варианты). Потому переставлениям присвоен такой вес в оценке.
 

jeka!

Просто Member
Короче я сделал вот это чудовище:
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) Сравнение слов с ошибками, т.к множество записей попадаются с неправильным написанием слова.
 
Сверху