【问题标题】:What substring algorithm (to find a string) does PHP use?PHP 使用什么子字符串算法(查找字符串)?
【发布时间】:2016-06-28 12:26:28
【问题描述】:

我一直在试图弄清楚子字符串算法(在另一个字符串中找到一个字符串)。 PHP使用,我在GitHub上的PHP源码中找到了如下一段代码:

我认为它使用了 Bruteforce,但我不确定,这就是为什么我在 SO 上寻求一些帮助。

zend_memnstr(const char *haystack, const char *needle, size_t needle_len, const char *end) {
    const char *p = haystack;
    const char ne = needle[needle_len-1];
    ptrdiff_t off_p;
    size_t off_s;

    if (needle_len == 1) { 
        return (const char *)memchr(p, *needle, (end-p));
    }

    off_p = end - haystack;
    off_s = (off_p > 0) ? (size_t)off_p : 0;

    if (needle_len > off_s) {
        return NULL;
    }

    if (EXPECTED(off_s < 1024 || needle_len < 3)) {
        end -= needle_len;

        while (p <= end) {
            if ((p = (const char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
                if (!memcmp(needle, p, needle_len-1)) {
                    return p;
                }
            }
            if (p == NULL) {
               return NULL;
            }
            p++;
        }
        return NULL;
    } else {
        return zend_memnstr_ex(haystack, needle, needle_len, end);
    }
}

【问题讨论】:

  • 在我看来像 Naïve string search 算法
  • 请注意,zend_memnstr_ex 被称为更长的字符串。该函数使用Sunday algorithm
  • 请注意,如果needle_len0 而不是返回haystack,则代码会调用未定义的行为。

标签: php c algorithm substring


【解决方案1】:

函数遵循以下步骤:

  • 它将needle 的最后一个字符加载到ne 中,从而在needle_len0 时调用未定义的行为。该字节将在后面的代码中用于通用循环。
  • 它是needle_len == 1 的特殊情况,将搜索委托给标准库函数memchr
  • 它计算要扫描的内存块的长度,允许end 指向haystack 之前并在这种情况下返回NULL。这是不一致的,因为此一致性检查仅针对 needle_len != 1memchr would be passed a huge length ofend - haystackifendpoints beforehaystack` 可能会调用未定义的行为。
  • 对于小于1023 的长度或小于3needle_len,该函数根据memchr 实现一个简单的算法。它扫描needle 的第一个字节,手动检查潜在匹配的最后一个字节,并使用memcmp 来验证其余的潜在匹配。此方法不一致:如果needle_len2,则更简单的扫描会更有效,如果所有情况下,应将少一个字节传递给memcmp,因为第一个字节已经匹配。
  • 对于其他情况,haystack 长度超过 1022 和 needle 超过 2 个字节,该函数使用在 zend_memnstr_ex 中实现的另一种方法,nwellnhof 表示是周日算法的变体。

有关高效字符串搜索的不同方法的更多说明:

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多