在PHP开发中,生成字符串的所有子串是一个常见的字符串处理需求,无论是做字符串匹配、数据统计还是算法练习,都可能会用到这个功能。所谓所有子串,指的是原字符串中连续的一段字符组成的所有可能字符串,包含单个字符的子串和原字符串本身。

实现思路分析
要生成字符串的所有子串,核心逻辑是通过两层循环遍历所有可能的子串起始位置和结束位置。第一层循环控制子串的起始索引,第二层循环控制子串的长度或者结束索引,然后调用substr函数截取对应位置的子串即可。
需要注意的是,PHP中字符串的索引是从0开始的,截取子串时要确保索引和长度的取值范围合法,避免出现越界的问题。
基础实现方式
下面是使用两层循环生成所有子串的基础实现代码:
<?php
/**
* 生成字符串的所有子串
* @param string $str 原字符串
* @return array 所有子串组成的数组
*/
function getAllSubstrings($str) {
$len = strlen($str);
$result = [];
// 第一层循环:控制子串起始位置
for ($i = 0; $i < $len; $i++) {
// 第二层循环:控制子串长度,从1到剩余字符长度
for ($j = 1; $j <= $len - $i; $j++) {
$subStr = substr($str, $i, $j);
$result[] = $subStr;
}
}
return $result;
}
// 测试示例
$testStr = "abc";
$substrings = getAllSubstrings($testStr);
echo "原字符串:{$testStr}n";
echo "所有子串:n";
print_r($substrings);
?>
上述代码中,外层循环$i表示子串的起始索引,内层循环$j表示子串的长度,每次循环调用substr($str, $i, $j)截取从$i位置开始,长度为$j的子串,然后存入结果数组。对于字符串"abc",运行后会得到数组["a","ab","abc","b","bc","c"],包含了所有的子串。
优化与注意事项
- 如果原字符串包含多字节字符(比如中文),需要使用
mb_strlen和mb_substr函数来替代strlen和substr,避免出现字符截断的问题。 - 如果不需要重复的子串,可以在存入结果数组前做去重处理,比如使用
array_unique函数。 - 当原字符串长度较长时,所有子串的数量是
n*(n+1)/2(n为字符串长度),会占用较多的内存,实际使用时需要根据场景评估是否必要生成所有子串。
多字节字符适配版本
下面是适配中文等多字节字符的实现代码:
<?php
/**
* 生成字符串的所有子串(适配多字节字符)
* @param string $str 原字符串
* @return array 所有子串组成的数组
*/
function getAllSubstringsMultiByte($str) {
$len = mb_strlen($str, 'UTF-8');
$result = [];
// 第一层循环:控制子串起始位置
for ($i = 0; $i < $len; $i++) {
// 第二层循环:控制子串长度,从1到剩余字符长度
for ($j = 1; $j <= $len - $i; $j++) {
$subStr = mb_substr($str, $i, $j, 'UTF-8');
$result[] = $subStr;
}
}
return $result;
}
// 测试示例
$testStr = "你好世界";
$substrings = getAllSubstringsMultiByte($testStr);
echo "原字符串:{$testStr}n";
echo "所有子串:n";
print_r($substrings);
?>
这个版本使用mb_strlen获取字符串长度,mb_substr截取子串,指定编码为UTF-8,可以正确处理中文等多字节字符,生成所有合法的子串。