前言
在 C++ 编程中,string 类是处理文本数据的核心工具,凭借动态扩容机制与丰富接口,成为日常开发中高频使用的基础组件。从算法题中的数字字符串处理,到实际项目中文本的解析与格式化,string 类的灵活应用直接影响代码效率与可读性。
初步认识 STL
STL 有六个组成部分:仿函数、算法、迭代器、空间配置器、容器、配接器。容器的本身是类。虽然有了这些,但是 C 语言里面的知识也不能忘。容器不一定都有反向迭代器。
string
使用 string 类时,必须包含 <string> 头文件及 using namespace std(或者 std::string)。string 不属于 STL,但是和 STL 很接近。
注意点:如果直接打印一个 char 类型的 \0,cout 会将其视为不可见字符(无输出),但不会终止打印。
和 vector 的区别:1. string 自带\0;2. string 有很多专属的接口,比如 +。
常见接口
以下介绍的都是成员函数。
string 类对象的常见构造
string()-- 构造空的 string 类对象,也就是空字符串string(const char*s)-- 用 C 语言风格的字符串构造 string 类对象,例如string s1("hello");string(size_t n,char c)-- 构造出的 string 类对象中包含 n 个字符 cstring(const string&s)-- 调用拷贝构造函数
引申注意:不加其他操作的话,字符串的类型是 const char* 或 char[]。string 不能隐式类型转换成字符串,字符串可以隐式类型转换成 string。
string 类对象的容量操作
size– 返回字符串有效字符长度(像这种不可能是负数的东西,库里面一般搞成 size_t 类型的)length– 返回字符串有效字符长度(和 size 没有区别)capacity– 返回空间总大小(没有算上\0)empty– 检测字符串是否为空串,是空返回 true,否则返回 falseclear– 清空有效字符,但是不会释放空间(size 变为 0,capacity 不会变)reserve– 为字符串预留空间(避免编译器频繁扩容浪费时间)resize– 将有效字符的个数改成 n 个,多出的空间用字符 c 填充(无 c 就用的 0)
string 类对象的访问及遍历操作
operator[pos]– 返回 pos 位置的字符(第一个位置是 [0])begin– 获取第一个字符的迭代器end– 获取最后一个字符的下一个位置的迭代器rbegin– 获取最后一个字符的迭代器rend– 获取第一个字符的上一个位置的迭代器(这里的迭代器其实是反向迭代器)- 范围 for
string 类对象的修改操作
push_back– 在字符串末尾插入字符 cappend– 在字符串末尾插入一个字符串operator+=– 在字符串末尾追加一个字符串(一般用的这个)c_str– 返回 C 风格的字符串(有时要用 c 语言函数,而那些函数识别不了 string 类型)find– 从字符串 pos 位置(含这里)开始往后找字符串,返回字符串第一个字符在字符串中的位置(返回的是第一次匹配时的)rfind– 从字符串 pos 位置(含这里)开始往前找字符串,返回字符串第一个字符在字符串中的位置(返回的是最后一次匹配时的)find_first_of– 在字符串中从左到右搜索,返回第一个出现在指定字符集合中的字符的位置find_last_of– 从右到左搜索,返回第一个出现在指定字符集合中的字符的位置substr– 在 str 中从 pos 位置开始,截取 n 个字符,然后将其返回
要注意的是:虽然 string 里面可以存中文,但是中文 ++ 的结果可能跟自己想的不一样,而且两个中文不一定只占 string[] 里面的 0 和 1 两个位置,可能会占更多位置。
string 类非成员函数
operator+– 尽量少用,因为传值返回,导致深拷贝效率低operator>>– 输入运算符重载operator<<– 输出运算符重载getline– 获取一行字符串(解决 cin 遇到空格不行的场景,getline 默认是遇到换行符停止)relational operators– 大小比较(也是用字典序去比较的)
包含在 string 头文件下的好用函数
stoi– 把数字字符串转换成 int 类型的stod– 把数字字符串转换成 double 类型的to_string– 把整数和浮点数转换成字符串
作业部分
力扣 字符串相加
主要问题:就是把数字和字符串混一起搞了(没去分辨哪个是数字,哪个是字符导致的问题)。数字转字符要 eg:to_string,字符转数字要 eg:a-'0'。混一起搞就会出现输出是 unicode 等乱码。
class Solution {
public:
string addStrings(string num1, string num2) {
string num3;
//让 num1 是最大的那个
if(num1.size()<num2.size()||(num1.size()==num2.size()&&num2>num1)) swap(num1,num2);
int ret = 0;
int partsum = 0;
int gap = num1.size()-num2.size();
for(int i = num2.size()-1;i>=0;i--)
{
partsum = num2[i]+num1[i+gap]+ret-'0'-'0';
ret = partsum/10;
partsum%=10;
num3+=to_string(partsum);//最后要反转一下
}
//num1 还有 gap 个数没搞
for(int i = gap-1;i>=0;i--)
{
partsum = num1[i]+ret-'0';
ret = partsum/10;
partsum%=10;
num3+=to_string(partsum);//最后要反转一下
}
if(ret==1) num3+=to_string(ret);
(num(),num());
num3;
}
};
HJ1 字符串最后一个单词的长度
注意点:像这种有空格的要读取时,不能用 cin,要 eg:getline(cin,s1)。还有 eg:for(int i = 0;i<n;i++); 和 for(int i = 0;i<n;i++){} 前两个是一个意思。for(int i = 0;i<n;i++) 后面紧跟 for 或者 while 的话形成嵌套循环。还有,注意是 2*k 不是 2k!
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s1;
getline(cin,s1);
int count = 0;
auto i = s1.end()-1;
for(;*i==' ';i--);
for(;*i!=' ';i--)
{
count++;
if(i == s1.begin()) break;
}
cout<<count<<endl;
return 0;
}


