Я играю со стоп-слова в рамках моего кода, у меня есть массив, полный слов, которые я хотел бы проверить, и массив слов, по которым я хочу проверить.
В данный момент я - цикличное выполнение через массив один в за один раз и удаление слова, если его in_array по сравнению со стоп-словом перечисляют, но интересно, существует ли лучший способ сделать его, я посмотрел на array_diff и такой однако, если у меня есть несколько стоп-слов в первом массиве, array_diff только, кажется, удаляет первое вхождение.
Фокус находится на скорости и использовании памяти, но скорости больше.
Редактирование -
Первый массив является исключительными словами, на основе комментариев блога (они обычно довольно длинны), второй массив является исключительными словами стоп-слов. Извините за не ясно давание понять
Спасибо
Простым подходом является использование str_replace или str_ireplace , которые могут принимать массив «иголок» (объектов для поиска), соответствующих замены, и множество «стогов сена» (вещи, над которыми нужно работать).
$haystacks=array(
"The quick brown fox",
"jumps over the ",
"lazy dog"
);
$needles=array(
"the", "lazy", "quick"
);
$result=str_ireplace($needles, "", $haystacks);
var_dump($result);
Это приводит к
array(3) {
[0]=>
string(11) " brown fox"
[1]=>
string(12) "jumps over "
[2]=>
string(4) " dog"
}
В стороне, быстрый способ очистить конечные пробелы, которые остаются, - это использовать array_map для вызова trim для каждого элемента
$result=array_map("trim", $result);
Недостатком использования str_replace является то, что он заменяет найденные совпадения в словах, а не только целые слова. Чтобы решить эту проблему, мы можем использовать регулярные выражения ...
Подход, использующий preg_replace , очень похож на приведенный выше, но стрелки являются регулярными выражениями, и мы проверяем наличие ' граница слова 'в начале и конце совпадения с использованием \ b
$haystacks=array(
"For we shall use fortran to",
"fortify the general theme",
"of this torrent of nonsense"
);
$needles=array(
'/\bfor\b/i',
'/\bthe\b/i',
'/\bto\b/i',
'/\bof\b/i'
);
$result=preg_replace($needles, "", $haystacks);
как насчет использования in_array
http://au.php.net/manual/en/function.in-array.php
Функция принимает иглу, которая является массивом.
bool in_array ( mixed $needle , array $haystack [, bool $strict ] )
В качестве альтернативы вы можете перебирать стоп-слова по одному и находить все совпадения
Если у вас уже есть два отсортированных массива, вы можете использовать этот алгоритм для удаления каждого элемента из массива A, который также находится в массиве B (в математических терминах: A \ B):
for ($i=0, $n=count($a), $j=0, $m=count($b); $i<$n && $j<$m; ) {
$diff = strcmp($a[$i], $b[$j]);
if ($diff == 0) {
unset($a[$i]);
$i++;
}
if ($diff < 0) {
$i++;
}
if ($diff > 0) {
$j++;
}
}
Это требует только O(n) шагов.
Другой подход заключается в использовании слов массива B в качестве ключей для индекса (используя array_flip
), итерации значений A и проверке, являются ли они ключом в индексе, используя array_key_exists
:
$index = array_flip($b);
foreach ($a as $key => $val) {
if (array_key_exists($val, $b)) {
unset($a[$key]);
}
}
Опять же, это O(n), поскольку это позволяет избежать поиска каждого значения в B для каждого значения в A, что было бы O(n2).