C++如何通过指针传参递归实现移除字符串中所有x字符
问题根因说明
你最初的值传递版本存在两个本质问题:
- 值传递会在每次函数调用时生成独立的字符串副本,函数内的所有修改都不会作用到main函数中的原始字符串,最终输出永远是未处理的输入值
- 递归逻辑存在断层:遇到首字符非'x'时直接递归子串,但没有保留当前首字符,最终处理结果会丢失所有非x字符
你改引用传递时遇到的编译错误,原因是str.substr()返回的是临时右值,C++不允许非const左值引用绑定临时右值,才会抛出"initial value of reference to non-const must be an lvalue"报错。
指针传参正确实现
指针传参不需要生成子串临时对象,直接通过索引标记当前处理位置即可,所有递归层级操作同一份原字符串,没有额外拷贝开销。
#include <iostream> #include <string> using namespace std; /** * @param pstr 指向待处理字符串的指针 * @param cur 当前递归需要检查的字符索引,默认从首位开始 */ void removex(string* pstr, int cur = 0) { // 递归终止条件:所有字符检查完毕 if (cur >= pstr->size()) { return; } // 注意:下标运算符优先级高于解引用,必须加括号包裹解引用逻辑 if ((*pstr)[cur] == 'x') { // 命中x字符,将后续所有字符向前移动1位覆盖当前x for (int i = cur; i < pstr->size() - 1; ++i) { (*pstr)[i] = (*pstr)[i+1]; } // 移除末尾冗余的重复字符 pstr->pop_back(); // 移位后当前位置为新字符,递归检查当前位置 removex(pstr, cur); } else { // 当前字符合法,递归检查下一位 removex(pstr, cur + 1); } } int main() { int t; cin >> t; while (t--) { string str; cin >> str; // 传入原始字符串的内存地址 removex(&str); cout << str << endl; } return 0; }
关键要点说明
- 递归调用指针参数时,直接传入已经定义好的指针变量即可,不需要重复取址,所有递归层级拿到的都是指向原字符串的地址,操作会直接作用到原始对象
- 访问指针指向对象的下标时,必须写成
(*pstr)[index]的形式:如果省略括号,会被编译器解析为*(pstr[index]),等价于把pstr当作字符串数组取第index个元素后解引用,会触发内存访问错误,这就是你之前无法正确获取索引字符的核心原因 - 用索引标记处理位置替代substr生成临时子串,从根源上避免了临时右值的产生,既不会触发编译错误,也减少了不必要的内存拷贝
内容的提问来源于stack exchange,提问作者parasguglani
相关产品推荐
相关产品推荐

