【LeetCode字符串#02】替换空格+IP地址无效化,reserve和resize的区别分析
替换空格
请实现一个函数,把字符串 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没有涉及开辟新空间->拷贝原有元素到新空间,那么将比喻中的小杯子换成伸缩杯子会准确一些)
IP 地址无效化
https://leetcode.cn/problems/defanging-an-ip-address/
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。
所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 "."。
示例 1:
输入:address = "1.1.1.1"
输出:"1[.]1[.]1[.]1"
示例 2:
输入:address = "255.100.50.0"
输出:"255[.]100[.]50[.]0"
提示:
给出的 address 是一个有效的 IPv4 地址
思路
和替换空格一样,也是先给字符串扩容(这里是IP字符串),然后用双指针从后向前遍历,遇到'.',指向新结尾的指针就开始补填充字符串
注意,这里的扩容大小是固定的,也就是说都是3*2,即三个'.',然后填充字符串("[.]" )的长度为2
代码
class Solution {
public:
string defangIPaddr(string address) {
int oldSize4Address = address.size();
//给地址数组扩容
address.resize(oldSize4Address + 3 * 2);//3是IP字符串中‘.’的数量,2是"[.]"的长度
int newSize4Address = address.size();
for(int oldp4IP = oldSize4Address - 1, newp4IP = newSize4Address - 1; oldp4IP < newp4IP; --oldp4IP, --newp4IP){
if(address[oldp4IP] == '.'){
address[newp4IP] = ']';
address[newp4IP - 1] = '.';
address[newp4IP - 2] = '[';
newp4IP -= 2;
}else{
address[newp4IP] = address[oldp4IP];
}
}
return address;
}
};
【LeetCode字符串#02】替换空格+IP地址无效化,reserve和resize的区别分析的更多相关文章
- 1108. IP 地址无效化
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ".". 示例 ...
- [LeetCode]1108. IP 地址无效化
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ".". 示例 ...
- leetcode-解题记录 1108. IP 地址无效化
题目: 给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ".". ...
- PHP算法之IP 地址无效化
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ".". 示例 ...
- IP 地址无效化
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本. 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 ".". 示例 ...
- LeetCode 1108. Defanging an IP Address (IP 地址无效化)
题目标签:String 题目给了我们一组 ip address,让我们把 . 变成 [.],这题可以用replace,但是这样做的话,好像没意义了.所以还是走一下array,具体看code. Java ...
- LeetCode算法训练 93.复原IP地址 78.子集 90.子集II
欢迎关注个人公众号:爱喝可可牛奶 LeetCode算法训练 93.复原IP地址 78.子集 90.子集II LeetCode 93. 复原 IP 地址 分析 字符串全部由数字组成,ipv4每一段数字不 ...
- python实现判断一个字符串是否是合法IP地址
#!usr/bin/env python #encoding:utf-8 ''''' __Author__:沂水寒城 功能:判断一个字符串是否是合法IP地址 ''' import re def jud ...
- 判断一个字符串是否是合法IP地址
# -*- coding: utf-8 -*- """ @File:test06_判断ip地址是否合法.py @E-mail:364942727@qq.com @Time ...
- 【面试题004】c/c++字符串,替换空格
一,c/c++字符串 1.C/C++中每个字符串都以字符’\0‘作为结尾,这样我们就能很方便地找到字符串的最后尾部. 由于这个原因每个字符串都有一个额外的开销,注意字符串越界的问题: 2.C/C+ ...
随机推荐
- 解锁前端新潜能:如何使用 Rust 锈化前端工具链
前言 近年来,Rust的受欢迎程度不断上升.首先,在操作系统领域,Rust 已成为 Linux 内核官方认可的开发语言之一,Windows 也宣布将使用 Rust 来重写内核,并重写部分驱动程序. ...
- Spring缓存是如何实现的?如何扩展使其支持过期删除功能?
前言:在我们的应用中,有一些数据是通过rpc获取的远端数据,该数据不会经常变化,允许客户端在本地缓存一定时间. 该场景逻辑简单,缓存数据较小,不需要持久化,所以不希望引入其他第三方缓存工具加重应用负担 ...
- elementui-自定表头和在input中遇见的问题
第一个问题:无法关闭 弹出框 <el-table :data="tableData" style="width: 100%"> <el-tab ...
- Vue中this.$options.data()和this.$data知多少?
1.场所描述 如何获取vue-data中的所有值? 如何获取vue-data中的某一个值? 如何获取vue-data中的初始值? 如何设置data中的值位初始值? 2.主角登场 this.$optio ...
- ABP 领域服务层学习记录
在ABP框架中有一个约定,所有的领域服务都应该继承并实现IDomainService接口,在领域层Core创建某一个实体的领域服务类,继承并实现IDomainService接口.在ABP框架中,领域服 ...
- Docker从认识到实践再到底层原理(九)|Docker Compose 容器编排
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总 然后就是博主最近最花时间的一 ...
- 【Linux】虚拟机太卡咋办?用云服务器Xshell配置Vmware虚拟机【技能篇】
[Linux]用云服务器Xshell配置Vmware虚拟机[技能篇] 强烈建议本篇收藏后再食用~ 文章目录 Xshell下载 配置Vmware 尾声 平时我们使用虚拟机,可能最烦人的问题就是卡顿了.今 ...
- SpringMVC的执行流程及初始化流程
今天大致来看一下Spring MVC的执行流程和初始化流程是什么样的 1,执行流程:也就是一个请求是怎么到我们Controller的 2,初始化流程:也就是那些 HandlerMapping.Hand ...
- 洛谷P1102 过河卒
P1102 过河卒 链接在此 过河卒 此题如果直接忽略掉马的影响的话,可以看出很简单的递推规律 即 \[dp[i][j]=dp[i-1][j]+dp[i][]j-1] \] 也就是说,由于卒只能走直线 ...
- 1.变量和简单的数据类型--《Python编程:从入门到实践》
1.1 变量 在Python中使用变量时,需要遵守一些规则和指南. 变量名只能包含字母.数字和下划线.变量名可以字母或下划线打头,但不能以数字打 头. 变量名不能包含空格,但可使用下划线来分隔其中的单 ...