PHP多次出现字符串中的单词

时间:2009-01-08 14:39:18

标签: php algorithm string substring

我需要检查一个字符串,看看其中是否有多个单词出现。所以基本上我会接受:

“google做爱”

但我不接受:

“google make google love”或“google make love love google”等。

有什么想法吗?真的不知道如何处理这个问题,我们将非常感谢任何帮助。

9 个答案:

答案 0 :(得分:5)

基于Wicked Flea代码:

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;
}

答案 1 :(得分:3)

试试这个:

function single_use_of_words($str) {
  $words = explode(' ', $str);
  $words = array_unique($words);
  return implode(' ', $words);
}

答案 2 :(得分:3)

不需要循环或数组:

<?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 :(得分:2)

<?php
$words = preg_split('\b', $string, PREG_SPLIT_NO_EMPTY);
$wordsUnique = array_unique($words);
if (count($words) != count($wordsUnique)) {
    echo 'Duplicate word found!';
}
?>

答案 4 :(得分:2)

正则表达方式肯定是我的选择。

我对一个包含Veynom函数和正则表达式的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次迭代)

当我运行测试超过10000次迭代时,我得到了

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

非RegExp解决方案也使用了更多内存。

所以..正则表达式对我来说,因为他们有一整罐汽油

修改
我测试的文本有重复的单词,如果没有,结果可能会有所不同。我会发布另一组结果。

更新
删除重复项(现为186个单词)后,1000次迭代的结果为:

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

关于evens

答案 5 :(得分:1)

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;
}

修改

整个测试脚本。请注意,当打印“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, , , 

答案 6 :(得分:1)

这似乎相当快。看到(对于所有答案),当你增加输入字符串的长度时,内存使用和时间的增加会很有趣。

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中检查每个单词是否为空。

答案 7 :(得分:0)

最简单的方法是遍历每个单词并检查所有先前的单词是否重复。

答案 8 :(得分:-1)