如何在JavaScript中将字符串拆分为首尾相同的子串或剩余字符
问题描述
我有如下字符串:
const str = "abbbaba";
我希望找到一种方法,将该字符串拆分为首尾字符相同的子串(子串内部除首尾外不含该字符),若剩余部分无法形成此类子串则保留剩余全部字符。
示例
该字符串应被拆分为:
["abbba", "ba"]
其中"abbba"是第一个子串,因为它以"a"开头并以"a"结尾,且中间没有"a"。最后一个子串以"b"开头,但没有对应的结尾"b",因此取剩余的全部字符。
另一种场景:
const str2 = "bbbabaa"
应拆分为:
["bb", "bab", "aa"]
当前尝试
以下是我针对字符串"abbabbabba"的最接近需求的实现,它返回["abba", "bb", "a", "bb", "a"]
而非期望的["abba", "bb", "abba"]
function splitSandwichedLetters(str) { const result = []; let start = 0; for (let i = 1; i < str.length; i++) { if (str[i] === str[start] && (i === str.length - 1 || str[i + 1] !== str[start])) { result.push(str.slice(start, i + 1)); start = i + 1; } } if (start < str.length) { result.push(str.slice(start)); } return result; } // Test const str1 = "abbabbabba"; console.log(splitSandwichedLetters(str1)); // Output: ["abbba", "ba"]
解决方案
原实现的问题在于额外添加了str[i + 1] !== str[start]的判断,导致错过符合要求的拆分位置。正确的逻辑应该是从当前起始位置出发,找到第一个与起始字符相同的后续字符,拆分出首尾相同且内部无该字符的子串;若找不到则保留剩余全部字符。
修改后的实现如下:
function splitSandwichedLetters(str) { const result = []; let start = 0; const length = str.length; while (start < length) { const currentChar = str[start]; // 从start+1的位置开始查找第一个与currentChar相同的字符 const nextMatchIndex = str.indexOf(currentChar, start + 1); if (nextMatchIndex !== -1) { // 拆分出符合要求的子串 result.push(str.slice(start, nextMatchIndex + 1)); start = nextMatchIndex + 1; } else { // 剩余部分无法形成符合要求的子串,直接加入结果 result.push(str.slice(start)); start = length; } } return result; } // 测试示例1 console.log(splitSandwichedLetters("abbbaba")); // ["abbba", "ba"] // 测试示例2 console.log(splitSandwichedLetters("bbbabaa")); // ["bb", "bab", "aa"] // 测试目标案例 console.log(splitSandwichedLetters("abbabbabba")); // ["abba", "bb", "abba"]
逻辑说明
- 初始化起始位置
start为0,结果数组为空; - 循环处理直到
start超出字符串长度:- 获取当前起始字符
currentChar; - 使用
str.indexOf从start+1的位置开始查找第一个与currentChar相同的字符索引; - 若找到匹配索引,拆分出从
start到该索引的子串(确保子串内部无currentChar),并更新start为索引+1; - 若未找到匹配索引,将剩余部分全部加入结果,结束循环;
- 获取当前起始字符
- 返回最终结果数组。
内容的提问来源于stack exchange,提问作者Abednego Nasila
相关产品推荐
相关产品推荐

