C++递归实现相邻相同字母删除功能出现Segmentation fault排查
分析你的递归实现问题及修复方案
首先,你的代码出现Segmentation Fault(段错误)主要是因为字符串越界访问和erase操作后的索引错误,下面逐一拆解问题:
1. 越界访问字符串元素
在你的for循环中,循环条件是i < s.length(),当i等于s.length()-1时,i+1就等于s.length(),而字符串的有效索引范围是0到s.length()-1,这时候访问s[i+1]就是访问了字符串末尾之后的非法内存,属于未定义行为,直接会触发段错误。
2. Erase操作后的索引错误
当你执行s.erase(s.begin()+i)删除第i个字符后,字符串的长度已经减少了1,原来的第i+1个字符现在已经移动到了第i个位置。这时候你再执行s.erase(s.begin()+i+1),相当于要删除的位置已经超出了当前字符串的长度(因为长度已经减1),同样会导致越界访问,引发段错误。
3. 递归逻辑的冗余问题
另外,你的递归调用后直接break并输出,虽然不是段错误的直接原因,但每次找到一对就立刻递归会打断当前循环的后续检查,逻辑上有点冗余,也会影响处理效率。
修复后的代码
下面是修正后的递归实现,解决了上述问题:
#include<iostream> #include<string> using namespace std; string super(string s) { bool foundPair = false; // 循环条件改为i < s.length()-1,确保i+1不会越界 for(int i = 0; i < (int)s.length() - 1; i++) { if(s[i] == s[i+1]) { // 用erase的区间版本,一次删除两个相邻字符,避免索引混乱 s.erase(s.begin() + i, s.begin() + i + 2); foundPair = true; break; } } // 找到配对就递归处理新字符串,否则直接返回原串 return foundPair ? super(s) : s; } int main() { string s; cin>>s; cout<<super(s)<<endl; return 0; }
修复点说明:
- 循环条件改为
i < s.length() - 1,彻底避免i+1的越界访问 - 使用
erase的区间重载版本,一次删除两个相邻字符,省去两次erase带来的索引偏移问题 - 用
foundPair标记是否找到配对,逻辑更清晰,避免循环内提前return的混乱
另外补充一点:递归实现对于超长字符串可能存在栈溢出风险,如果需要处理极长的输入,建议改用迭代方式(比如借助栈结构)来实现,不过在字符串长度适中的场景下,递归版本是可以正常工作的。
内容的提问来源于stack exchange,提问作者Bavya
相关产品推荐
相关产品推荐

