找出单词B中的每个字母是否出现在单词A中,这是php中最快的函数

时间:2013-06-24 04:43:33

标签: php sorting strpos

我有三个功能: _sort,_strpos,_array_int

<?php
class timer{
    private $_start;
    private $_end;
    public function program_begin(){
        $this->_start = microtime(true);
    }
    public function program_end(){
        $this->_end = microtime(true);
    }
    public function get_time(){
        $time_use = ($this->_end - $this->_start)*1000;
        echo $time_use."ms\n";
    }
};
$t = new timer();
$test_cnt = $argv[1];
$s_len1 = $s_len2 = $argv[2];
$t->program_begin();
for($j = 0; $j<$test_cnt; $j++){
    for($i = 0; $i < $s_len1; $i++)
        $s1 .= chr(rand()%26+97);

    for($i = 0; $i < $s_len2; $i++)
        $s2 .= chr(rand()%26+97);

    $flag = call_user_func($argv[3],$s1, $s2);
    $s1=$s2="";
}
$t->program_end();
$t->get_time();

function _sort($s1, $s2){
    for($i = 0; $i < strlen($s1); $i++)
        $arr[] = $s1[$i];

    sort($arr);

    for($i = 0; $i < strlen($s2); $i++)
        if(!search_part($arr, $s2[$i]))
            return false;

    return true;

}
function search_part($arr, $key){
    $s = 0; 
    $e = count($arr)-1;
    while($s<=$e){
        $m = (int)(($s+$e)/2);
        if($arr[$m] > $key)
            $e = $m-1;

        if($arr[$m] < $key)
            $s = $m+1;

        if($arr[$m] == $key)
            return true;
    }
    return false;
}

function _strpos($s1, $s2){
    for($i = 0; $i < strlen($s2); $i++)
        if(strpos($s1,$s2[$i]) === false)
            return false;

    return true;
}

function _array($s1, $s2){
    for($i = 0; $i < strlen($s1); $i++)
        $arr[$s1[$i]] = 1;

    for($i = 0; $i < strlen($s2); $i++)
        if(!isset($arr[$s2[$i]]))
            return false;

    return true;
}

function _array_int($s1,$s2){
    for($i = 0; $i < strlen($s1); $i++)
        $arr[ord($s1[$i])] = 1;

    for($i = 0; $i < strlen($s2); $i++)
        if(!isset($arr[ord($s2[$i])]))
            return false;

    return true;
}

我认为时间的复杂性:
_sort(如func A): O(nlgn)
_array_int(作为功能B): O(n)
_strpos(作为功能C): O(n ^ 2)

因此速度似乎是 B> A> C

但测试结果是: C> B> A
我无法解释为什么C最快。

测试它像 php test.php test_count word_lenght test_func

2 个答案:

答案 0 :(得分:0)

你的O(n ^ 2)执行速度比其他原因快的原因之一是因为它包含一个错误。

if(!strpos($s1,$s2[$i]))
        return false;

这实际上意味着“如果$s2[$i] OR 中没有字符$s1,则$ s1中的 FIRST 字符,返回false。 “,因为字符串索引从0开始。这可能不是你想要的,因为当两个字符串以相同的字符开头时,它会在false中立即返回O(1)(您可以使用 if(strpos($s1,$s2[$i]) === false)

来解决此问题

其次,您用于测试的输入对于您获得的结果至关重要。由于O(10*n)仍为O(n),因此无法保证对于小输入,O(n)算法执行速度比O(n²)快,依此类推。当n增长得足够大时,这种保证是渐近结果。此外,与“最坏情况”相反,算法中的特性也会导致特定情况下的不同性能。例如,如果其中一个字符串明显小于另一个字符串,或其他字符串,则通过简单地以交换顺序($s2, $s1)传递参数,您的二次函数可能会导致与相比非常不同的性能 满足特殊条件,特别是因为您允许算法尽快快速返回false,而不必将所有字符串一直处理到最后。

最后,您的O(n)算法通常应该在3中表现最佳,特别是在输入大小增加时,但不一定保证它会在每个时表现更好输入

答案 1 :(得分:-1)

如果你只是使用str_split匹配一个字符串是另一个字符串的一部分。您的代码似乎不必要地复杂。

  $string1 = "ABCD";
  $string2 = "AABCDEF";

  $origin = str_split($string1);
  $other = str_split($string2);

  foreach ($origin as $char) {
      if (in_array($char, $other)) {
          //char found
      } else {
          //char not found
      }
  }