我有三个功能: _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
答案 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
}
}