PHP中如何实现字符串连续交集的统计功能?
PHP实现str_intersection函数:统计最长连续公共子串长度
针对你需要的统计两个小写拉丁ASCII字符串连续交集的需求,这里提供高效的实现方案,替代之前错误的str_split()+array_intersect()方法(该方法会统计所有公共字符总数,而非连续子串)。
需求明确
函数需返回两个字符串中最长连续公共子串的长度:
- 输入
$str1 = "lorem ipsum"、$str2 = "rem"时,返回3(最长连续公共子串为"rem") - 输入
$str2 = "xzy"时,返回0(无连续公共子串)
实现代码
利用PHP内置字符串函数的高性能特性,结合滑动窗口思路实现:
function str_intersection(string $str1, string $str2): int { $len1 = strlen($str1); $len2 = strlen($str2); // 空字符串直接返回0 if ($len1 === 0 || $len2 === 0) { return 0; } // 确保较长字符串作为被搜索目标,减少循环次数 if ($len1 < $len2) { [$str1, $str2] = [$str2, $str1]; [$len1, $len2] = [$len2, $len1]; } // 从最长可能的子串开始匹配,找到即返回(提前终止,提升性能) for ($length = $len2; $length > 0; $length--) { for ($start = 0; $start <= $len2 - $length; $start++) { $substr = substr($str2, $start, $length); if (str_contains($str1, $substr)) { return $length; } } } return 0; }
基础测试示例
echo str_intersection("lorem ipsum", "rem"); // 输出3 echo str_intersection("lorem ipsum", "xzy"); // 输出0
针对你的场景示例说明
如果你的场景实际需求是统计needle作为连续子串在haystack中出现的次数(而非最长长度),可使用以下实现:
function str_intersection_count(string $haystack, string $needle): int { $needleLen = strlen($needle); if ($needleLen === 0) { return 0; } $count = 0; $pos = 0; // 遍历所有匹配位置,避免重叠匹配(如需允许重叠,将$pos += $needleLen改为$pos +=1) while (($pos = strpos($haystack, $needle, $pos)) !== false) { $count++; $pos += $needleLen; } return $count; }
测试你的场景代码:
$strings = ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur']; $needle = 'lo'; $intersections = []; foreach ($strings as $str) { $intersections[] = str_intersection_count($str, $needle); } print_r($intersections);
输出结果:
Array ( [0] => 1 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 0 )
注:你的场景预期结果中[2] => 1可能是笔误,"dolor"中不存在连续的"lo"子串。
性能优势
- 依赖PHP内置的
str_contains()、strpos()等底层C实现函数,比纯PHP循环拆分字符串的性能提升显著,适合处理大量字符串。 - 最长子串匹配逻辑采用从长到短的顺序,找到匹配后立即返回,减少不必要的计算。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

