复试,string

std::string 是标准库提供的一个用于处理字符串的类,它位于 <string> 头文件中。相比于 C 风格的字符串(以 '\0' 结尾的字符数组),std::string 类提供了更方便、更安全且功能更强大的字符串操作方式。以下将从概念、内容、用法等方面详细介绍 std::string

概念

std::string 是一个模板类 std::basic_string<char> 的 typedef,它封装了字符序列,并提供了一系列成员函数来操作这些字符序列。使用 std::string 可以避免许多 C 风格字符串可能出现的问题,如缓冲区溢出、手动内存管理等。

内容

std::string 对象本质上是一个动态数组,它可以根据需要自动调整大小以容纳不同长度的字符串。它包含了一系列字符,并在内部管理这些字符的存储和生命周期。

用法

1. 包含头文件

要使用 std::string,首先需要包含 <string> 头文件:

#include <string>

2. 声明和初始化

std::string 提供了多种初始化方式:

#include <iostream>
#include <string>

int main() {
    // 1. 默认初始化,创建一个空字符串
    std::string s1; 

    // 2. 使用字符串字面量初始化
    std::string s2 = "Hello"; 

    // 3. 使用另一个 std::string 对象初始化
    std::string s3(s2); 

    // 4. 指定重复字符初始化
    std::string s4(5, 'A'); 

    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;
    std::cout << "s3: " << s3 << std::endl;
    std::cout << "s4: " << s4 << std::endl;

    return 0;
}

3. 字符串操作

连接字符串

可以使用 + 运算符或 += 运算符来连接字符串:

#include <iostream>
#include <string>

int main() {
    std::string s1 = "Hello";
    std::string s2 = " World";
    std::string s3 = s1 + s2; // 使用 + 运算符连接
    s1 += s2; // 使用 += 运算符连接

    std::cout << "s3: " << s3 << std::endl;
    std::cout << "s1: " << s1 << std::endl;

    return 0;
}

获取字符串长度

可以使用 size()length() 成员函数来获取字符串的长度:

#include <iostream>
#include <string>

int main() {
    std::string s = "Hello";
    std::cout << "字符串长度: " << s.size() << std::endl;
    std::cout << "字符串长度: " << s.length() << std::endl;

    return 0;
}

访问字符串中的字符

可以使用下标运算符 []at() 成员函数来访问字符串中的单个字符:

#include <iostream>
#include <string>

int main() {
    std::string s = "Hello";
    std::cout << "第一个字符: " << s[0] << std::endl;
    std::cout << "第二个字符: " << s.at(1) << std::endl;

    return 0;
}

[] 运算符不进行边界检查,而 at() 函数会进行边界检查,如果越界会抛出 std::out_of_range 异常。

查找子字符串

可以使用 find() 成员函数来查找子字符串在原字符串中的位置:

#include <iostream>
#include <string>

int main() {
    std::string s = "Hello World";
    size_t pos = s.find("World");
    if (pos != std::string::npos) {
        std::cout << "子字符串 'World' 的位置: " << pos << std::endl;
    } else {
        std::cout << "未找到子字符串" << std::endl;
    }

    return 0;
}

std::string::npos 是一个静态常量,表示查找失败。

字符串截取

可以使用 substr() 成员函数来截取子字符串:

#include <iostream>
#include <string>

int main() {
    std::string s = "Hello World";
    std::string sub = s.substr(6, 5); // 从位置 6 开始截取长度为 5 的子字符串
    std::cout << "截取的子字符串: " << sub << std::endl;

    return 0;
}

4. 字符串比较

可以使用 ==!=<> 等运算符来比较两个字符串的大小,也可以使用 compare() 成员函数进行比较:

#include <iostream>
#include <string>

int main() {
    std::string s1 = "apple";
    std::string s2 = "banana";

    if (s1 < s2) {
        std::cout << "s1 小于 s2" << std::endl;
    }

    int result = s1.compare(s2);
    if (result < 0) {
        std::cout << "s1 小于 s2" << std::endl;
    }

    return 0;
}

5. 输入输出

可以使用 std::cinstd::cout 进行字符串的输入输出:

#include <iostream>
#include <string>

int main() {
    std::string s;
    std::cout << "请输入一个字符串: ";
    std::cin >> s; // 读取一个单词
    std::cout << "你输入的字符串是: " << s << std::endl;

    std::string line;
    std::cout << "请输入一行字符串: ";
    std::getline(std::cin, line); // 读取一行字符串
    std::cout << "你输入的一行字符串是: " << line << std::endl;

    return 0;
}

std::cin >> s 会在遇到空格或换行符时停止读取,而 std::getline(std::cin, line) 会读取一整行字符串。

std::string push_backpop_back 操作

push_back 操作

功能

push_back 函数用于在 std::string 对象的末尾添加一个字符。这是一种动态增长字符串的方式,类似于在容器末尾添加元素。

用法

void push_back( char ch );

其中,ch 是要添加到字符串末尾的字符。

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello";
    std::cout << "原始字符串: " << str << std::endl;

    // 使用 push_back 添加字符
    str.push_back('!');
    std::cout << "添加字符后的字符串: " << str << std::endl;

    return 0;
}

代码解释

  • 首先定义了一个 std::string 对象 str 并初始化为 "Hello"
  • 然后调用 push_back 函数,将字符 '!' 添加到 str 的末尾。
  • 最后输出添加字符后的字符串。

pop_back 操作

功能

pop_back 函数用于移除 std::string 对象末尾的字符。如果字符串为空,调用该函数会导致未定义行为,所以在调用前最好先检查字符串是否为空。

用法

void pop_back();

示例代码

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello!";
    std::cout << "原始字符串: " << str << std::endl;

    // 检查字符串是否为空
    if (!str.empty()) {
        // 使用 pop_back 移除末尾字符
        str.pop_back();
        std::cout << "移除末尾字符后的字符串: " << str << std::endl;
    }

    return 0;
}

代码解释

  • 定义一个 std::string 对象 str 并初始化为 "Hello!"
  • 使用 empty 函数检查字符串是否为空,避免对空字符串调用 pop_back 导致未定义行为。
  • 如果字符串不为空,调用 pop_back 函数移除末尾的字符 '!'
  • 输出移除末尾字符后的字符串。

inserterase

insert 函数

insert 函数用于在字符串的指定位置插入字符、字符串或字符序列。它有多种重载形式,以下是一些常见的用法示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello World";

    // 在指定位置插入单个字符
    str.insert(5, 1, ',');
    std::cout << "插入单个字符后: " << str << std::endl;

    // 在指定位置插入字符串
    std::string insertStr = " beautiful";
    str.insert(6, insertStr);
    std::cout << "插入字符串后: " << str << std::endl;

    // 在指定位置插入字符串的一部分
    str.insert(17, insertStr, 1, 5); 
    std::cout << "插入字符串的一部分后: " << str << std::endl;

    return 0;
}

代码解释

  • str.insert(5, 1, ','):在位置 5 处插入 1 个字符 ','
  • str.insert(6, insertStr):在位置 6 处插入整个字符串 insertStr
  • str.insert(17, insertStr, 1, 5):在位置 17 处插入 insertStr 从索引 1 开始长度为 5 的子字符串。

erase 函数

erase 函数用于删除字符串中的部分字符。同样有多种重载形式,下面是示例代码:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello beautiful World";

    // 删除指定位置开始的指定长度的字符
    str.erase(6, 10);
    std::cout << "删除指定长度字符后: " << str << std::endl;

    // 删除指定位置的单个字符
    str.erase(5);
    std::cout << "删除单个字符后: " << str << std::endl;

    // 删除从指定位置到字符串末尾的所有字符
    str.erase(2);
    std::cout << "删除到末尾的字符后: " << str << std::endl;

    return 0;
}

代码解释

  • str.erase(6, 10):从位置 6 开始删除长度为 10 的字符。
  • str.erase(5):删除位置 5 处的单个字符。
  • str.erase(2):删除从位置 2 到字符串末尾的所有字符。

字符串匹配

std::string 中,常见的字符串匹配方式有使用 findrfindfind_first_offind_last_of 等函数,以下是详细介绍:

find 函数

用于查找子字符串或字符第一次出现的位置,如果找到则返回其位置,未找到则返回 std::string::npos

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello World";
    size_t pos = str.find("World");
    if (pos != std::string::npos) {
        std::cout << "子字符串 'World' 第一次出现的位置: " << pos << std::endl;
    } else {
        std::cout << "未找到子字符串" << std::endl;
    }

    return 0;
}

rfind 函数

用于查找子字符串或字符最后一次出现的位置,同样未找到返回 std::string::npos

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello World, World";
    size_t pos = str.rfind("World");
    if (pos != std::string::npos) {
        std::cout << "子字符串 'World' 最后一次出现的位置: " << pos << std::endl;
    } else {
        std::cout << "未找到子字符串" << std::endl;
    }

    return 0;
}

find_first_of 函数

查找字符串中第一个与指定字符集中任意字符匹配的位置。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello World";
    std::string chars = "aeiou";
    size_t pos = str.find_first_of(chars);
    if (pos != std::string::npos) {
        std::cout << "第一个元音字母出现的位置: " << pos << std::endl;
    } else {
        std::cout << "未找到元音字母" << std::endl;
    }

    return 0;
}

find_last_of 函数

查找字符串中最后一个与指定字符集中任意字符匹配的位置。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello World";
    std::string chars = "aeiou";
    size_t pos = str.find_last_of(chars);
    if (pos != std::string::npos) {
        std::cout << "最后一个元音字母出现的位置: " << pos << std::endl;
    } else {
        std::cout << "未找到元音字母" << std::endl;
    }

    return 0;
}

通过上述 inserterase 函数以及各种字符串匹配函数,你可以方便地对 std::string 对象进行修改和查找操作。

#复试练习#
考研机试常用的数据结构 文章被收录于专栏

考研机试常用的数据结构

全部评论

相关推荐

迷茫的大四🐶:哇靠,哥们,啥认证啊,副总裁实习,这么有实力嘛
一起聊美团
点赞 评论 收藏
分享
从大一开始就开始学习Java,一路走来真的不算容易,每次面试都被压力,不过这次终于达成了自己的一大心愿!时间线和面经:8.17-投递9.1-一面实习+项目拷打看门狗机制讲一下redis加锁解锁的本身操作是什么Lua脚本是干什么的udp和tcp讲一下流量控制讲一下令牌桶算法说一下大端和小端是什么线程和协程有什么区别怎么切换协程切换的时候具体做了什么对于程序来说,你刚才提到的保存和恢复现场,这个现场有哪些信息udp优势现在有一个客户端和服务端,要实现TCP的通信,我们的代码要怎么写服务器怎么感知有新的连接怎么处理多个客户端的请求连接TCP怎么处理粘包和分包现在有两个文件,然后每个文件都有一亿条URL,每个的长度都很长,要怎么快速查找这两个文件共有的URLHashmap底层说一下怎么尽量提升插入和查询的效率如果要查找快,查询快,还有解决非空的问题,怎么做LoadingCache了解吗手撕:堆排序9.4-二面部门的leader,超级压力面拷打实习+项目,被喷完全没东西类的加载到垃圾回收整个底层原理讲一遍类加载谁来执行类加载器是什么东西,和进程的关系Java虚拟机是什么东西,和进程的关系如果我们要执行hello&nbsp;world,那虚拟机干了什么呢谁把字节码翻译成机器码,操作时机是什么Java虚拟机是一个执行单元吗Java虚拟机和操作系统的关系到底什么,假如我是个完全不懂技术的人,举例说明让我明白一个操作系统有两个Java程序的话,有几个虚拟机有没有单独的JVM进程存在启动一个hello&nbsp;world编译的时候,有几个进程JVM什么时候启动比如执行一条Java命令的时候对应一个进程,然后这个JVM虚拟机到底是不是在这个进程里面,还是说要先启动一个JVM虚拟机的进程垃圾回收机制的时机能手动触发垃圾回收吗垃圾回收会抢占业务代码的CPU吗垃圾回收算法简单说说垃圾回收机制的stop&nbsp;the&nbsp;world存在于哪些时机垃圾回收中的计算Region的时候怎么和业务代码并行执行假如只有一个线程,怎么实现并行Java为什么要这么实现Java效率比C++慢很多,那为什么还要这样实现Java虚拟机到底是什么形式存在的说一下Java和C++的区别还有你对Java设计理念的理解无手撕面试结束的时候,我真的汗流浃背了,面试官还和我道歉,说他是故意压力面想看看我的反应的,还对我给予了高度评价:我当面试官这么多年,你是我见过最好的一个9.9-三面临时通知的加面,就问了三十分钟项目9.11-hr面问过往经历,未来计划,想从腾讯实习中得到什么?当场告知leader十分满意我,所以直接ochr面完一分钟官网流程变成录用评估中,30分钟后mt加微信告知offer正在审批9.15-offer这一次腾讯面试体验真的不错,每个面试官能感觉到专业能力很强,反馈很足,比起隔壁某节真是好太多以后就是鹅孝子了
三本咋了:当面试官这么多年你是我见过的最好的一个
你面试被问到过哪些不会的...
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务