You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在替换字符串空格为@40时需使用string.erase()?

问题解答:替换空格为何必须先删除再插入?

核心原因:替换是“替换”而非“插入”

你要做的是把1个字符的空格替换成3个字符的@40,本质是用新的字符序列完全替换掉原来的单个空格。如果直接调用insert(i, "@40"),原有的空格不会消失,只会在它前面插入@40,结果就变成了@40+空格的错误组合(比如原"Hello I"会变成"Hello@40 I"),完全不符合需求。

举个具体的索引变化例子:

  • 原字符串索引5的位置是空格:[H,e,l,l,o, ,I,...]
  • 直接insert后:[H,e,l,l,o,@,4,0, ,I,...],空格还留在索引8的位置,等于多了一个冗余字符,结果错误。
  • 先erase删除空格,再insert@40,才能得到正确的替换结果:[H,e,l,l,o,@,4,0,I,...]

当前代码的问题

  • 你定义的temp变量完全没用,属于冗余代码,应该直接删除。
  • 这种erase+insert的方式时间复杂度是O(n²):每次erase和insert都会移动后面的所有字符,字符串越长,效率越低。
  • 虽然操作的是原字符串,但string的insert在需要扩容时会申请新的内存空间,严格来说并不完全符合O(1)额外空间的题目要求。

符合O(1)空间复杂度的正确实现

正确的做法是先统计空格数量,计算替换后的总长度,通过resize预先分配足够空间,再从后往前遍历替换,全程不需要额外辅助内存,时间复杂度为O(n):

#include<iostream>
using namespace std;

void replaceSpaces(string &str) {
    // 统计空格数量
    int spaceCount = 0;
    int originalLength = str.length();
    for (char c : str) {
        if (c == ' ') spaceCount++;
    }
    // 计算新长度:原长度 + 每个空格多占2个字符(@40是3个,替换1个空格,净增2)
    int newLength = originalLength + spaceCount * 2;
    str.resize(newLength);
    
    // 从后往前替换,避免覆盖未处理的字符
    int i = originalLength - 1;
    int j = newLength - 1;
    while (i >= 0) {
        if (str[i] == ' ') {
            str[j--] = '0';
            str[j--] = '4';
            str[j--] = '@';
        } else {
            str[j--] = str[i];
        }
        i--;
    }
}

int main() {
    string s = "Hello I love coding Coding Ninjas India";
    replaceSpaces(s);
    cout << "Ans--> " << s << endl;
    return 0;
}

从后往前替换的优势

  • 不会覆盖还未处理的原字符,不需要额外空间存储临时数据。
  • resize只是扩展原字符串的内存空间,没有使用额外的辅助内存,完全符合O(1)空间要求。

内容的提问来源于stack exchange,提问作者vivek shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:40:13