C/C++ 刷题集:string 类常见考点与高频题型(2025-2026面试/比赛视角)
string 是 C++ 中使用频率最高的标准库类之一,也是面试和算法比赛中最容易踩坑的地方之一。
下面按照难度递增 + 考察频率的顺序整理 string 相关的高频考点和典型题目类型,适合快速查漏补缺或系统复习。
一、基础但极易出错的考点(必须0失误)
| 序号 | 考点 | 典型错误写法 | 正确/推荐写法 | 考察频率 |
|---|---|---|---|---|
| 1 | string + char* / char | s += “hello”; s = s + ‘a’; | s += ‘a’; s.push_back(‘a’); | ★★★★★ |
| 2 | string::npos 的类型 | if(s.find(“x”) == -1) | if(s.find(“x”) == string::npos) | ★★★★★ |
| 3 | substr(start, len) vs substr(pos) | s.substr(5) 以为取后面所有 | s.substr(5) 就是从5到末尾,长度可省略 | ★★★★ |
| 4 | 字符串比较大小(字典序) | s1 > s2 | 直接用 < > == != 即可(按字典序) | ★★★★ |
| 5 | 清空 string 最快的方式 | s = “”; s.clear(); | s.clear(); 或 s = string(); | ★★★ |
| 6 | reserve() 和 capacity() 的关系 | reserve(100) 后 size()==100 | reserve 只影响 capacity,size 不变 | ★★★★ |
| 7 | at() vs operator[] | s[100](越界未定义行为) | s.at(100) 会抛异常,[] 不检查 | ★★★★ |
二、高频算法题型 & 典型代码模板(比赛/面试必备)
1. 字符串查找与统计类(出现频率最高)
// 统计子串出现次数(可重叠/不可重叠两种写法)
int count_substr(const string& s, const string& t, bool overlap = false) {
int cnt = 0, pos = 0;
while ((pos = s.find(t, pos)) != string::npos) {
cnt++;
pos += overlap ? 1 : t.length();
}
return cnt;
}
2. 字符串分割(最常考,手写 split)
// 方法1:istringstream(最常用,面试最稳)
vector<string> split(const string& s, char delim = ' ') {
vector<string> res;
istringstream iss(s);
string token;
while (getline(iss, token, delim)) {
if (!token.empty()) res.push_back(token);
}
return res;
}
// 方法2:find + substr(不依赖流,性能更好)
vector<string> split2(const string& s, char delim) {
vector<string> res;
size_t start = 0;
while (true) {
size_t end = s.find(delim, start);
if (end == string::npos) {
res.push_back(s.substr(start));
break;
}
res.push_back(s.substr(start, end - start));
start = end + 1;
}
return res;
}
3. 字符串替换(全部替换 / 部分替换)
// 全部替换(推荐写法)
string& replace_all(string& s, const string& from, const string& to) {
size_t pos = 0;
while ((pos = s.find(from, pos)) != string::npos) {
s.replace(pos, from.length(), to);
pos += to.length();
}
return s;
}
4. 去除首尾空白 / 全部空白
// C++11 后推荐写法(trim)
string trim(const string& str) {
size_t first = str.find_first_not_of(" \t\n\r\f\v");
if (first == string::npos) return "";
size_t last = str.find_last_not_of(" \t\n\r\f\v");
return str.substr(first, last - first + 1);
}
// 去除所有空白(erase-remove idiom)
s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());
5. 字符串转数字 & 数字转字符串(安全写法)
// string → int/long/double(推荐)
int to_int (const string& s) { return stoi(s); }
long to_long (const string& s) { return stol(s); }
double to_double(const string& s) { return stod(s); }
// 带异常处理版本(生产常用)
optional<long long> safe_stoll(const string& s) {
try {
size_t pos;
long long val = stoll(s, &pos);
if (pos != s.size()) return nullopt; // 后面有非法字符
return val;
} catch (...) {
return nullopt;
}
}
// 数字 → string(C++11 后首选 to_string)
string num2str = to_string(12345) + "." + to_string(3.14);
三、LeetCode / NowCoder / 面试高频 string 题目(分类)
简单 / 基础类
- 剑指 Offer 05. 替换空格
- 反转字符串
- 反转字符串 II
- 有效的字母异位词
- 最长回文串
中等 / 字符串模拟
- 3. 无重复字符的最长子串(滑动窗口)
- 5. 最长回文子串(中心扩展 / Manacher / DP)
- 8. 字符串转换整数 (atoi)(边界最多)
- 字母异位词分组
- 反转字符串中的单词(或剑指 Offer 58 – I)
- 找到字符串中所有字母异位词
- 回文子串(计数)
较难 / 构造 / KMP / 字符串哈希
- 正则表达式匹配
- 通配符匹配
- 最长有效括号
- 最小覆盖子串
- 最短回文串(KMP)
- 回文对
- 密钥格式化
四、string 面试/比赛最常被问到的 trick & 易错点
s += s[i]连续拼接 → 可能产生二次分配,建议用reservestring s = "abc" + 'd';合法,但char c = 'd'; s = "abc" + c;非法find()从 0 开始,rfind()从后往前append()/push_back()比+=更高效(尤其循环中)- C++20
starts_with/ends_with/contains(非常方便) string_view(C++17)在只需要只读子串时性能更好
有哪一类题目或哪个具体题目你想看详细题解 + 多种写法对比(比如最长回文子串的五种解法、atoi 的边界处理、KMP 模板等),可以直接告诉我~