1. 为什么需要专门整理string类题目?
在C/C++编程中,字符串处理是每个开发者都无法绕开的基础课题。string作为标准库中最常用的容器之一,其重要性不亚于数组和链表。但很多初学者(甚至一些有经验的开发者)在面试和实际开发中,仍然会在string操作上栽跟头。
我整理这个刷题集的初衷,源于去年面试候选人的真实经历:一位自称"精通C++"的应聘者,在面对"反转字符串中的单词"这道基础题时,竟然用了3个嵌套循环才勉强实现。这让我意识到,系统性地掌握string操作技巧有多么重要。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. string类的核心操作全解析
2.1 基础操作:从构造到遍历
string类的构造函数有7种重载形式,但实际开发中最常用的是这3种:
cpp复制string s1; // 空字符串
string s2("hello"); // 从C风格字符串构造
string s3(5, 'a'); // 包含5个'a'的字符串
遍历字符串时,我强烈推荐使用迭代器而非下标访问:
cpp复制for(auto it = s.begin(); it != s.end(); ++it) {
cout << *it;
}
注意:在C++11及以上版本中,范围for循环更简洁:
cpp复制for(char c : s) { cout << c; }
2.2 字符串查找的进阶技巧
find()系列方法是最常用的查找函数,但很多人不知道它们可以指定起始位置:
cpp复制size_t pos = s.find("ll", 3); // 从下标3开始查找"ll"
更高效的查找策略是KMP算法,特别适合需要多次匹配的场景。这里给出一个next数组的生成实现:
cpp复制vector<int> getNext(const string& p) {
vector<int> next(p.size());
next[0] = -1;
int j = -1;
for(int i = 1; i < p.size(); ++i) {
while(j >= 0 && p[i] != p[j+1]) {
j = next[j];
}
if(p[i] == p[j+1]) {
++j;
}
next[i] = j;
}
return next;
}
2.3 字符串修改的陷阱与优化
erase()和insert()操作的时间复杂度都是O(n),在循环中使用时要特别小心:
cpp复制// 错误示范:每次eras
