为何在替换字符串空格为@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
相关产品推荐
相关产品推荐

