我很感兴趣知道PHP用于爆炸/内爆函数的算法是什么,它们的时间复杂度是多少?
提前谢谢。
答案 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_memnstr
(php_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。