如何实现保留原顺序的字符串全子串生成函数?
实现思路与方案
首先明确:你要的其实是原字符串的所有顺序保持一致的子序列(包含连续子串)——和排列不同,这类序列的字符顺序完全和原串一致,不会出现像"cba"这种打乱顺序的情况。下面是几种实用的实现思路:
1. 递归回溯法
核心就是对每个字符做「选或不选」的决策,逐步构建子序列:
- 从字符串第一个字符开始,每到一个位置,有两个选择:把当前字符加入正在构建的子序列,或者跳过它
- 当遍历到字符串末尾时,把当前构建好的子序列丢进Set里(自动去重)
- 举个例子:处理"abc"时,先选a,然后选b,再选c得到"abc";选a、跳过b、选c得到"ac";以此类推,覆盖所有可能的合法序列
2. 迭代逐步构建法
这种方法更直观,从空序列开始一步步堆出新的子序列:
- 初始化一个Set,先放个空字符串(不需要的话可以跳过)
- 逐个遍历字符串里的每个字符:
- 把当前Set里所有已有的子序列拿出来,每个后面都追加当前字符,生成一批新子序列
- 把这些新子序列加到Set里
- 遍历完所有字符后,把空字符串移除(如果不需要),转成列表就是结果
- 比如处理"abc":一开始Set是{""},加a后变成{"", "a"};加b后变成{"", "a", "b", "ab"};加c后就得到所有合法子序列
3. 位掩码法
用二进制数来标记哪些字符被选中,适合对数字敏感的场景:
- 假设字符串长度是n,那么总共有2^n种可能的子序列(每个字符有选或不选两种状态)
- 遍历从1到2^n-1的所有整数(从1开始是跳过空串,从0开始包含)
- 对每个整数,看它的二进制每一位:如果第i位是1,就把原串第i个字符拿出来组成子序列
- 把生成的子序列丢进Set去重,最后转成列表
去重说明
因为允许用Set,不管哪种方法,只要把生成的子序列往Set里塞,就能自动去掉重复的(比如输入"aab"时,重复的"a"会被Set自动合并成一个)
示例代码(JavaScript)
function getAllSubstrings(str) { const result = new Set(); result.add(''); // 初始包含空串,不需要可删除 for (const char of str) { // 先把当前Set转成数组,避免遍历过程中修改集合导致的问题 const currentSubs = Array.from(result); currentSubs.forEach(sub => result.add(sub + char)); } result.delete(''); // 移除空串,不需要可删除 return Array.from(result); } // 测试调用 console.log(getAllSubstrings("abc")); // 输出:["a", "b", "c", "ab", "ac", "bc", "abc"]
内容的提问来源于stack exchange,提问作者Fluxian
相关产品推荐
相关产品推荐

