本文最后更新于 34 天前,其中的信息可能已经有所发展或是发生改变。
蓝桥杯算法竞赛高频必备,字符串处理题的基础工具,无需死记所有函数原型,重点掌握竞赛高频用法+避坑点+组合技巧。
🔧 通用基础规则
- 下标从0开始,最后一个字符下标为
s.size()-1 - 未找到指定内容时,返回常量
string::npos - 单引号
'c'表示单个字符(char),双引号"str"表示C风格字符串(const char*),二者不可混用 - 需包含头文件:
#include <string>
📌 一、构造函数(3.1.2)
核心功能:创建string对象时的初始化
竞赛高频写法
| 写法 | 效果 | 示例 | 输出 |
|---|---|---|---|
string s; | 空字符串 | string s; | 空 |
string s("C串"); | C风格字符串初始化 | string s("hello"); | hello |
string s(s2); | 拷贝另一个string | string s1("a"); string s2(s1); | a |
string s(n, 'c'); | n个单个字符初始化 | string s(5, 'a'); | aaaaa |
🚨 核心避坑
string(n, 'c') 的第二个参数必须是单引号包裹的单个字符,不可写 string(5, "a")(类型不匹配报错)。
📌 二、赋值操作(3.1.3)
核心功能:给已存在的string对象重新赋值
竞赛首选写法
| 写法 | 效果 | 示例 | 输出 |
|---|---|---|---|
s = "C串"; | 赋值C风格字符串 | s = "world"; | world |
s = s2; | 赋值另一个string | s1="a"; s2=s1; | a |
s.assign(n, 'c'); | 赋值n个单个字符 | s.assign(3, 'b'); | bbb |
s.assign("C串", n); | 赋值C串的前n个字符 | s.assign("hello", 3); | hel |
📌 三、字符串拼接(3.1.4)
核心功能:在字符串末尾追加内容
1. += 运算符(80%场景够用,优先用)
| 写法 | 效果 | 示例 | 输出 |
|---|---|---|---|
s += "C串"; | 追加C串 | s="a"; s+="bc"; | abc |
s += 'c'; | 追加单个字符 | s="ab"; s+='c'; | abc |
s += s2; | 追加另一个string | s1="a"; s2="b"; s1+=s2; | ab |
2. append 精准拼接(仅截取部分时用)
| 写法 | 效果 | 示例 | 输出 |
|---|---|---|---|
s.append("C串", n); | 追加C串的前n个字符 | s="he"; s.append("llo",2); | hell |
s.append(s2, pos, n); | 追加s2中pos开始的n个字符 | s2="abcde"; s="h"; s.append(s2,1,3); | hbcd |
🚨 核心避坑
append(s2, pos, n) 中,pos是s2的起始下标,n是要截取的字符数,非结束下标。
📌 四、查找和替换(3.1.5)
核心功能:查找字符/子串的下标 + 替换指定位置内容
1. 查找(find/rfind)
| 写法 | 效果 | 关键场景 |
|---|---|---|
s.find("子串/字符", pos=0); | 从pos开始找首次出现的下标 | 判断子串是否存在、找分隔符(:/.)首次位置 |
s.rfind("子串/字符"); | 找最后一次出现的下标 | 拆分文件名/后缀(找最后一个.)、拆分路径 |
✅ 判断是否找到的唯一正确写法:
if (s.find("a") != string::npos) {
// 找到了
}
2. 替换(replace)
核心原型:s.replace(pos, n, 新内容) → 从pos开始,替换n个字符为新内容
| 示例 | 效果 | 输出 |
|---|---|---|
s="13812345678"; s.replace(3,4,"****"); | 手机号脱敏(替换中间4位) | 138****5678 |
s="abc123"; s.replace(3,3,"xyz"); | 替换指定位置子串 | abcxyz |
🚨 核心避坑
- 查找未找到时,必须用
!= string::npos判断,下标0会被判定为false - replace的第二个参数n是要替换的字符数,非结束下标
📌 五、字符串比较(3.1.6)
核心功能:比较两个字符串的大小,按字符ASCII码逐字符对比
竞赛首选:直接用运算符
| 运算符 | 效果 | 示例 | 结果 |
|---|---|---|---|
s1 == s2 | 判断相等 | "abc"=="abd" | false |
s1 != s2 | 判断不等 | "abc"!="abd" | true |
s1 > s2 | 按ASCII比大小 | "abd">"abc" | true |
s1 < s2 | 按ASCII比大小 | "abc"<"abcd" | true |
📋 比较规则
- 逐字符对比,直到找到第一个不同字符,ASCII大的字符串整体更大
- 若一个是另一个的前缀(如abc/abcd),短字符串更小
- 大小写敏感:A(65) < a(97),”Apple” < “apple”
- 空字符串
""小于任何非空字符串
📌 六、字符存取(3.1.7)
核心功能:读取/修改字符串中的单个字符
竞赛高频写法
| 写法 | 效果 | 场景 |
|---|---|---|
s[pos] | 读取/修改pos位置的字符 | 逐字符遍历、统计字符、修改字符 |
实战示例(蓝桥杯高频)
string s = "abc123";
// 逐字符统计数字个数
int cnt = 0;
for (int i=0; i= '0' && s[i] <= '9') cnt++;
}
// 小写转大写
s[i] -= 32; // a(97)-A(65)=32
🚨 核心避坑
下标范围必须是0 ~ s.size()-1,不可写s[s.size()](越界导致程序崩溃)。
📌 七、插入和删除(3.1.8)
1. 插入(insert)
| 写法 | 效果 | 竞赛场景 |
|---|---|---|
s.insert(pos, "C串/string"); | 在pos位置插入整串 | 加前缀(+86)、插分隔符(-/ ) |
s.insert(pos, n, 'c'); | 在pos位置插入n个单个字符 | 补0(凑固定长度)、插占位符(#/*) |
2. 删除(erase)
| 写法 | 效果 | 竞赛场景 |
|---|---|---|
s.erase(pos, n); | 从pos开始删除n个字符 | 删分隔符、删无用字符(空格/数字) |
s.erase(pos); | 从pos开始删除到末尾 | 删字符串后缀(去掉多余字符) |
实战示例(格式补全/清理)
string s = "1234";
s.insert(0, 6, '0'); // 补0凑10位 → 0000001234
s.erase(0, 2); // 删前2个0 → 00001234
🚨 核心避坑
pos的合法范围:
- 插入:
0 ~ s.size()(pos=s.size()表示插在末尾) - 删除:
0 ~ s.size()-1(超过则报错)
📌 八、子串(substr)(3.1.9)
核心功能:提取字符串中的指定子串,蓝桥杯顶级高频
核心原型
string substr(int pos = 0, int n = npos)
• pos:子串起始下标(必选)
* n:提取的字符数(可选,省略则提取到末尾)
高频用法
| 写法 | 效果 | 示例 | 输出 |
|---|---|---|---|
s.substr(pos); | 从pos提取到末尾 | s="hello"; s.substr(2); | llo |
s.substr(pos, n); | 从pos提取n个字符 | s="hello"; s.substr(1,3); | ell |
蓝桥杯黄金组合:find/rfind + substr(拆分字符串)
// 拆分文件名和后缀(超高频)
string filename = "test.txt";
size_t dot = filename.rfind("."); // 找最后一个.的下标
string name = filename.substr(0, dot); // 文件名:test
string suffix = filename.substr(dot); // 后缀:.txt
🚨 核心避坑
- n是要提取的字符数,非结束下标:如提取下标2~4的子串,应写
substr(2,3),非substr(2,4) - pos不可超过
s.size()-1(越界直接报错)
🏆 蓝桥杯string核心黄金技巧(必背)
- 拆分字符串:
find/rfind找分隔符(:/.)+substr提取子串(文件名/手机号/路径拆分) - 字符串脱敏:
substr提取前后部分 ++=拼接占位符(****) - 格式补全:
insert(pos, n, '0')凑固定长度、加前缀(+86/NO.) - 字符统计/修改:
[]运算符逐字符遍历(统计数字/元音、转大小写、替换字符) - 判断子串存在:
if (s.find("子串") != string::npos)(唯一正确写法) - 删除无用内容:
erase删分隔符/空格,清理字符串格式
以上内容覆盖蓝桥杯99%的string使用场景,核心是灵活组合各模块功能解决实际问题。