PHP множественные вхождения слов в строке - PullRequest
2 голосов
/ 08 января 2009

Мне нужно проверить строку, чтобы узнать, встречается ли какое-либо слово в ней несколько раз. Так что в основном я приму:

"Гугл занимается любовью"

но я не принимаю:

"Google занимается любовью в Google" или "Google занимается любовью в Google" и т. Д.

Есть идеи? На самом деле не знаю, как подойти к этому, любая помощь будет принята с благодарностью.

Ответы [ 9 ]

5 голосов
/ 08 января 2009

Основано на коде злой блохи:

function single_use_of_words($str) {  
   $words = explode(' ', trim($str));  //Trim to prevent any extra blank
   if (count(array_unique($words)) == count($words)) {
      return true; //Same amount of words
   }   
   return false;
}
3 голосов
/ 08 января 2009

Нет необходимости в циклах или массивах:

<?php

$needle = 'cat';
$haystack = 'cat in the cat hat';

if ( occursMoreThanOnce($haystack, $needle) ) {
    echo 'Success'; 
} 

function occursMoreThanOnce($haystack, $needle) {
    return strpos($haystack, $needle) !== strrpos($haystack, $needle);
}

?>
3 голосов
/ 08 января 2009

Попробуйте это:

function single_use_of_words($str) {
  $words = explode(' ', $str);
  $words = array_unique($words);
  return implode(' ', $words);
}
2 голосов
/ 09 января 2009

Я бы выбрал способ регулярного выражения.

Я провел небольшой тест на строке из 320 слов с функцией Вейном и регулярным выражением

function preg( $txt ) {
    return !preg_match( '/\b(\w+)\b.*?\1/', $txt );
}

Вот тест

$time['preg'] = microtime( true );

for( $i = 0; $i < 1000; $i++ ) {
    preg( $txt );
}

$time['preg'] = microtime( true ) - $time['preg'];


$time['veynom-thewickedflea'] = microtime( true );

for( $i = 0; $i < 1000; $i++ ) {
    single_use_of_words( $txt );
}

$time['veynom-thewickedflea'] = microtime( true ) - $time['veynom-thewickedflea'];

print_r( $time );

И вот результат, который я получил

Array
(
    [preg] => 0.197616815567
    [veynom-thewickedflea] => 0.487532138824
)

Это говорит о том, что решение RegExp, а также более лаконичное решение, более чем в два раза быстрее. (для строки из 320 слов и 1000 итераций)

Когда я запускаю тест на 10 000 итераций, я получаю

Array
(
    [preg] => 1.51235699654
    [veynom-thewickedflea] => 4.99487900734
)

Решение, отличное от RegExp, также использует намного больше памяти.

Итак ... Регулярные выражения для меня, потому что у них есть полный бак газа

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

Обновление
При удалении дубликатов (теперь 186 слов) результаты для 1000 итераций:

Array
(
    [preg] => 0.235826015472
    [veynom-thewickedflea] => 0.2528860569
)

О вечера

2 голосов
/ 08 января 2009
<?php
$words = preg_split('\b', $string, PREG_SPLIT_NO_EMPTY);
$wordsUnique = array_unique($words);
if (count($words) != count($wordsUnique)) {
    echo 'Duplicate word found!';
}
?>
1 голос
/ 08 января 2009

Это выглядит довольно быстро. Было бы интересно увидеть (для всех ответов), как увеличивается использование памяти и занимаемое время при увеличении длины входной строки.

function check($str) {
    //remove double spaces
    $c = 1;
    while ($c) $str = str_replace('  ', ' ', $str, $c);

    //split into array of words
    $words = explode(' ', $str);
    foreach ($words as $key => $word) {
        //remove current word from array
        unset($words[$key]);
        //if it still exists in the array it must be duplicated
        if (in_array($word, $words)) {
            return false;
        }
    }
    return true;
}

Редактировать

Исправлена ​​проблема с несколькими пробелами. Я не уверен, что лучше удалить их в начале (как у меня) или проверить, что каждое слово не пусто в foreach.

1 голос
/ 08 января 2009
function Accept($str)
{
    $words = explode(" ", trim($str));
    $len = count($words);
    for ($i = 0; $i < $len; $i++)
    {
        for ($p = 0; $p < $len; $p++)
        {
            if ($p != $i && $words[$i] == $words[$p])
            {
                return false;
            }
        }
    }
    return true;
}

EDIT

Весь тестовый скрипт. Обратите внимание, что при печати «false» php просто печатает ничего, кроме true печатается как «1».

<?php

    function Accept($str)
    {
            $words = explode(" ", trim($str));
            $len = count($words);
            for ($i = 0; $i < $len; $i++)
            {
                    for ($p = 0; $p < $len; $p++)
                    {
                            if ($p != $i && $words[$i] == $words[$p])
                            {
                                    return false;
                            }
                    }
            }
            return true;
    }

echo Accept("google makes love"), ", ", Accept("google makes google love"), ", ",
    Accept("google makes love love google"), ", ", Accept("babe health insurance babe");


?>

Печатает правильный вывод:

1, , , 
0 голосов
/ 08 января 2009

Регулярное выражение с обратной ссылкой

http://www.regular -expressions.info / php.html

http://www.regular -expressions.info / named.html

0 голосов
/ 08 января 2009

Самый простой способ - циклически проходить каждое слово и проверять дубликаты по всем предыдущим словам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...