PHP爆炸/内爆的时间复杂性

时间:2012-12-28 23:39:12

标签: php algorithm time-complexity

我很感兴趣知道PHP用于爆炸/内爆函数的算法是什么,它们的时间复杂度是多少?

提前谢谢。

3 个答案:

答案 0 :(得分:7)

string.c中,您可以看到算法。它从约1021 line开始。

    if (p2 == NULL) {
    add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);
    } else {
    do {
        add_next_index_stringl(return_value, p1, p2 - p1, 1);
        p1 = p2 + Z_STRLEN_P(delim);
    } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
             --limit > 1);

    if (p1 <= endp)
        add_next_index_stringl(return_value, p1, endp-p1, 1);
    }

它只是一个循环所以我称之为它有O(N)复杂度。并仔细检查代码。它扫描字符串并将结果添加到return_value。是的线性

答案 1 :(得分:6)

简答:对于单字节分隔符,explode的时间复杂度为Ο( N );但对于多字节分隔符,其时间复杂度为Ο( N 2 )。

implode显然属于Ο( N ),因为它只是将各个部分粘合在一起。

扩展回答: basic algorithm of explode将在字符串中搜索分隔符的出现次数,并将附带的子字符串复制到新的阵列。

要在字符串中查找分隔符的位置,它会使用internal function zend_memnstrphp_memnstr只是zebd_memnstr的别名)。对于单个字节,它只调用进行线性搜索的memchr(因此在Ο( N )中)。

但是对于超过一个字节的分隔符值,它会调用memchr来搜索字符串中分隔符的第一个字节的位置,测试分隔符的最后一个字节是否出现在 string 中的预期位置,并调用memcmp以检查其间的字节。因此,它基本上检查分隔符是否包含在字符串中是否包含任何可能的位置。这听起来有点像Ο( N 2 )。

现在让我们看看这个算法的最坏情况,其中模式的第一个和最后一个字节都适合,但倒数第二个没有,例如:

string:     aaaabaaaa
delimiter:  aaaaaa

aaaabaaaa
aaaaXa      (1+1+5)
 aaaX?a     (1+1+4)
  aaX??a    (1+1+3)
   aX???a   (1+1+2)

X表示memcmp?个未知字节不匹配。括号中的值是统一度量中的时间复杂度。这总结为

   i M -lolo( N / 2)到Σ(2 + i ) (ñ / 2)

  

N - M +1)·2 +Σ i - j for i 从1到ceil( N / 2), j 从1到 M -floor( N < / EM> / 2)-1。

由于 i 从<1> N 的Σ i 可以用 N 表示( N +1)/ 2 =( N 2 + N )/ 2,我们也可以写:

  

N - M +1)·2 +(ceil( N / 2) 2 + ceil( N / 2))/ 2 - (( M -lolo( N / 2)-1) 2 < / SUP> +(中号 -floor(ñ / 2)-1))/ 2

为简单起见,我们假设 N M 都是偶数,所以我们可以省略'ceil'和'floor':

  

N - M +1)·2 +(( N / 2 + 1) 2 + N / 2 + 1)/ 2 - (( M - N / 2-1) 2 +(中号 - ñ / 2)-1)/ 2
  =( N - M +1)·2 + N 2 / 8 + 3· N / 4 + 1 - (( M - N / 2-1) 2 +( M < / EM> - ñ / 2)-1)/ 2

此外,我们可以估算值: N - M &lt; N M - N / 2-1&lt; 名词的。因此我们得到:

  

N ·2 + N 2 / 8 + 3· N / 4 + 1 - (< EM>ñ 2 + ñ)/ 2
  &LT; N ·2 + N 2 + 4· N - N 2 + ñ

这证明具有多个字节分隔符的explode在Ο( N 2 )中。

答案 2 :(得分:3)

根据GitHub上的PHP消息来源,它是线性的。您可以查看explode() here