【九章斩题录】C/C++:替换空格(JZ5)

简介: 【九章斩题录】C/C++:替换空格(JZ5)

    精品题解 🔥 《九章斩题录》  👈 猛戳订阅




JZ5 - 替换空格

📚 题目:请实现一个函数,将一个字符串 中的每个空格替换成 " %20 " 。例如当字符串为 We Are Happy.  则经过替换之后的字符串为 We%20Are%20Happy 。

💭 示例:I/O

输入:"We Are Happy"
返回:"We%20Are%20Happy"
输入:" "
返回:"%20"

✅ 模板:C语言

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param s string字符串 
 * @return string字符串
 */
char* replaceSpace(char* s ) {
    // write code here
}

✅ 模板:C++

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串
     */
    string replaceSpace(string s) {
        // write code here
    }
};

「 法一 」暴力美学

💡 思路:两次循环遍历整个数组,第一次循环寻找空格的位置,第二次循环将空格后的字符整体后移 2 个单位 (腾出空间给 %20),然后再将 %20 插入即可。因为 ''%20'' 为 3 个字符,分别是 (%, 2, 0),因为空格处用来放置 '%',所以只需腾出 2 个空间给 '2' 和 '0' 即可。

循环次数为两次,因此时间复杂度为 ,空间复杂度为

💬 代码演示:C++

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串
     */
    string replaceSpace(string s) {
        // 统计空格数
        int i = 0;
        int count = 0;
        for (i = 0; i < s.size(); i++) {
            if (s[i] == ' ') {
                count++;
            }
        }
        // 重新开大小,大小为 旧字符串大小 + 空格数 x 2
        // 这样就有足够的位置放 %20了
        // 原字符串空格放%,新开的放 2 和 0
        s.resize(s.size() + count * 2);
        i = 0;
        int j = 0;
        while (i < s.size()) {
            if (s[i] == ' ') {
                // 整体后移两个单位
                for (j = s.size() - 1; j > i + 2; j--) {
                    s[j] = s[j - 2];
                }
                s[i] = '%';
                s[i + 1] = '2';
                s[i + 2] = '0';
            }
            else {
                i++;
            }
        }
        return s;   // 返回原字符串
    }
};

「 法二 」另开数组

💡 思路:我们直接重新开一个字符数组,依次读取原整个字符串的内容,读到空格就在后面加上 '‘%20'' 然后继续读。其主要思路如下:

① 创建一个新的字符型数组,用于存放替换空格后的字符串。

② 从头到尾遍历字符串 ,遍历到 \0 为止。

③ 对每个字符都进行判断,判断当前字符是否为空格,如果为空格就分别向后插入 %, 2, 0。

④ 如果当前字符不是空格,就将当前字符串的字符直接加到新数组中。

⑤ 最后记得在新数组末尾手动加上 \0,最后返回新数组即可,此时就实现了空格的替换。

这种方法需要创建新的空间,不修改源字符串,这种方法非常易于理解和实现,属于 "重新来过" 的思想。其时间复杂度为 ,空间复杂度为

💬 代码演示:C

char* replaceSpace(char* s ) {
    char arr[10000] = {0};
    int i = 0;
    while (*s != '\0') {
        if (*s == ' ') {
            arr[i++] = '%';
            arr[i++] = '2';
            arr[i++] = '0';
        }
        else {
            arr[i++] += *s; 
        }
        s++;
    }
    arr[i] = '\0';
    return arr;
}

「 法三 」反向搜空格然后替换(利用 rfind + replace)

💡 思路:有现成的 replace 接口可以拿来替换,又有现成的 find 接口可以拿来查找空格。直接调接口来解决问题,岂不美哉?这里我们用 rfind 反向查找,从字符串 的末尾向前查找空格,如果找到就调用 replace 把空格替换成 '%20' 即可。

💬 代码:C++

class Solution {
public:
    string replaceSpace(string s) {
        int end = s.size() - 1;    // 字符串s的最后一个元素的下标
        while (string::npos != s.rfind(' ', end)) {
            int space = s.rfind(' ', end);    // 倒着找空格,避免覆盖
            s.replace(space, 1, "%20");       // 将字符串s中空格开始的1个字符替换为%20
            end = space;                      // 下次从空格前一个位置开始查找
        }
        return s;
    }
};

先定义 end 用于记录最后一个字符的位置,然后倒着遍历字符串。这里的循环条件是判断 rfind 是否为 npos,因为当findrfind 在字符串中找不到指定字符或子字符串时,它们会返回 string::npos。如果是 npos 那就说明没找到空格,说明查找完毕了,就结束循环。如果有空格,我们就记录空格的位置,然后调用 replace,把空格替换成 %20,然后更新我们的 end。每次循环都会判断是否存在空格,如果从右向左找一遍没有空格也就没有必要在进入循环,说明没有需要替换的,或者已经替换完了,这时直接 return s 即可。

⚡ 代码简化:

class Solution {
public:
    string replaceSpace(string s) {
        int space, end = s.size() - 1;
        for (; (space = s.rfind(' ', end)) != string::npos; end = space)
            s.replace(space, 1, "%20");
        return s;
    }
};

「 整活 」不用C++了,Python 一行代码搞定

"人生苦短,我用 Python…… "

不用做了,用隔壁蟒蛇直接一行结束了。

return s.replace(' ', "%20")

📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2023.5.30
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

牛客网. 剑指offer 题解 [EB/OL]. []. https://www.nowcoder.com/exam/oj/ta?tpId=1kon

相关文章
|
算法 C语言 C++
【九章斩题录】C/C++:二维数组中的查找(JZ4)
【九章斩题录】C/C++:二维数组中的查找(JZ4)
110 0
|
存储 C++ 容器
【九章斩题录】C/C++:数组中重复的数字(JZ3)
【九章斩题录】C/C++:数组中重复的数字(JZ3)
62 0
|
10天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
51 18
|
10天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
37 13
|
10天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5
|
10天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
26 5
|
10天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
32 4
|
11天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
26 3
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
75 2
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
128 5