Если вы можете использовать простой текст вместо массивов для сравнения, и если я правильно понял, где ваша цель, вы можете использовать levenshtein php функцию (которая обычно используется для создания google-like ' Вы имели ввиду функцию ...? В поисковых системах php).
Он работает противоположным образом, который вы используете: вернуть разницу между двумя строками.
Пример:
<?php
function check($a, $b) {
return levenshtein($a, $b);
}
$a = 'this is just a test';
$b = 'this is not test';
$c = 'this is just a test';
echo check($a, $b) . '<br />';
//return 5
echo check($a, $c) . '<br />';
//return 0, the strings are identical
?>
Но я не знаю точно, улучшит ли это скорость выполнения ... но, возможно, да, вы убрали много циклов foreach и функцию array_merge.
EDIT:
Простой тест на скорость (это 30-секундный скрипт, его не на 100%, а):
function check($terms_in_article1, $terms_in_article2) {
$length1 = count($terms_in_article1); // number of words
$length2 = count($terms_in_article2); // number of words
$all_terms = array_merge($terms_in_article1, $terms_in_article2);
$all_terms = array_unique($all_terms);
foreach ($all_terms as $all_termsa) {
$term_vector1[$all_termsa] = 0;
$term_vector2[$all_termsa] = 0;
}
foreach ($terms_in_article1 as $terms_in_article1a) {
$term_vector1[$terms_in_article1a]++;
}
foreach ($terms_in_article2 as $terms_in_article2a) {
$term_vector2[$terms_in_article2a]++;
}
$score = 0;
foreach ($all_terms as $all_termsa) {
$score += $term_vector1[$all_termsa]*$term_vector2[$all_termsa];
}
$score = $score/($length1*$length2);
$score *= 500; // for better readability
return $score;
}
$a = array('this', 'is', 'just', 'a', 'test');
$b = array('this', 'is', 'not', 'test');
$timenow = microtime();
list($m_i, $t_i) = explode(' ', $timenow);
for($i = 0; $i != 10000; $i++){
check($a, $b);
}
$last = microtime();
list($m_f, $t_f) = explode(' ', $last);
$fine = $m_f+$t_f;
$inizio = $m_i+$t_i;
$quindi = $fine - $inizio;
$quindi = substr($quindi, 0, 7);
echo 'end in ' . $quindi . ' seconds';
печать: конец 0,36765 секунд
Второй тест:
<?php
function check($a, $b) {
return levenshtein($a, $b);
}
$a = 'this is just a test';
$b = 'this is not test';
$timenow = microtime();
list($m_i, $t_i) = explode(' ', $timenow);
for($i = 0; $i != 10000; $i++){
check($a, $b);
}
$last = microtime();
list($m_f, $t_f) = explode(' ', $last);
$fine = $m_f+$t_f;
$inizio = $m_i+$t_i;
$quindi = $fine - $inizio;
$quindi = substr($quindi, 0, 7);
echo 'end in ' . $quindi . ' seconds';
?>
печать: конец 0,05023 секунд
Так что, да, похоже, быстрее.
Было бы неплохо попробовать много элементов массива (и много слов для левенштейна)
2 ° EDIT
При одинаковом тексте скорость кажется равной методу Левенштейна:
<?php
function check($a, $b) {
return similar_text($a, $b);
}
$a = 'this is just a test ';
$b = 'this is not test';
$timenow = microtime();
list($m_i, $t_i) = explode(' ', $timenow);
for($i = 0; $i != 10000; $i++){
check($a, $b);
}
$last = microtime();
list($m_f, $t_f) = explode(' ', $last);
$fine = $m_f+$t_f;
$inizio = $m_i+$t_i;
$quindi = $fine - $inizio;
$quindi = substr($quindi, 0, 7);
echo 'end in ' . $quindi . ' seconds';
?>
печать: конец 0,05988 секунд
Но это может занять более 255 символов:
Обратите внимание, что сложность этого
Алгоритм O (N ** 3), где N является
длина самой длинной строки.
и даже может возвращать аналогичное значение в процентах:
function check($a, $b) {
similar_text($a, $b, $p);
return $p;
}
Еще одно редактирование
А как насчет создания функции базы данных, чтобы выполнять сравнение непосредственно в запросе sql, вместо того, чтобы извлекать все данные и зацикливать их?
Если вы используете Mysql, взгляните на этот (функция Левенштейна, сделанная вручную, по-прежнему 255 символов)
Иначе, если вы находитесь на Postgresql, этот другой (много функций, которые должны быть оценены)