替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = "We are happy."
输出:"We%20are%20happy."
思路
一个错误思路:
class Solution {
public:
string replaceSpace(string s) {
for(int i = 0; i < s.size(); i++){
if(s[i] == " "){
s[i] = "%20";
}
}
return s;
}
};
写python可能可以这么干,但是c++不行
注意审题,我们要插入的 "%20" 是什么东西?这是个字符串
而空格,也就是" ",它是个字符
直接把字符串插到字符的位置,第一,位置不够插不进去,第二,要插也是得一个一个插
这里依然用双指针的方法
维护一对双指针,从字符串末尾向头部遍历
两个指针的起点分别为旧字符串和新字符串的末尾,即 i 和 j
当 i 碰到空格时,j从当前位置开始,往前填充待插入的字符串,然后将j跳转到填充结束的位置
如果 i 没碰到空格,正常将 i 位置与 j 位置的字符交换
代码
class Solution {
public:
string replaceSpace(string s) {
//先统计空格个数,为扩容做准备
int count = 0;
int sOldLen = s.size();//扩容前字符串的长度
for(int i = 0; i < sOldLen; i++){
if(s[i] == ' '){
count++;
}
}
//字符串扩容
//如示例1,有两个空格,字符串长度为8,如果用待插入的字符串代替空格后,新字符串的长度应该为12(8-2+6)
s.resize(sOldLen + count*2);//注意不是reserve
int sNewLen = s.size();
//维护一对双指针,从字符串末尾开始遍历
//指针的起点分别为旧字符串长度下的末尾和新字符串长度下的末尾
for(int i = sOldLen - 1,j = sNewLen - 1; i < j; i--, j--){
//如果i没有碰到空格,交换i与j的字符
if(s[i] != ' '){
s[j] = s[i];
}else{//碰到空格,将j接下来的三位依次替换为插入值
s[j] = '0';
s[j - 1] = '2';
s[j - 2] = '%';
j-=2;
}
}
return s;
}
};
易错点
1、字符串扩容
C++中并没有专门的字符串的类型,因此一个字符串实际上就是一个字符数组
是数组就可以扩容
2、reserve和resize的区别
这里容易拿reserve去给数组扩容
首先得区分清楚概念
对于(数组)容器来说,在初始化时,能够描述其"大小"的是两个参数:capacity和size
capacity是容器初始化时的赋值,指的是容器最多能容纳的元素个数(所指容器可以还没创建)
size则是指当前容器中实际的元素个数(所指容器已经创建)
举个例子:
"一个瓶子的容积是550ml(capacity),现在里面装有300ml(size)水"
回到reserve和resize
reserve一般用于为容器预留空间,所谓预留即该容器还没有被创建,等到容器需要创建的时候再按预留空间的大小创建。也就是说reserve可以修改capacity,但不能修改size,因为容器还没创建,没有size属性
再举个例子:
"这次买(创建)的罐装可乐才250ml,不够喝,下次(预留操作,reserve)要买500ml的(修改了下次创建容器时的大小)"
resize则会同时修改capacity和size,此时容器的可用空间会变成新的capacity的大小,
例子:
"我有个小杯子(原容器),里面有300ml水,不够装,我现在马上拿一个500ml的大杯子(扩容,resize)把原来的水装进去,现在够了"
(上述比喻不知道是否贴切,如果resize没有涉及开辟新空间->拷贝原有元素到新空间,那么将比喻中的小杯子换成伸缩杯子会准确一些)
标签:02,容器,空格,字符串,reserve,LeetCode,resize,size From: https://www.cnblogs.com/DAYceng/p/17107080.html