substr)操作string 的各种操作解决复杂字符串问题s.substr(pos, len):提取从 pos 开始长度为 len 的子串s.substr(pos):提取从 pos 到末尾的子串上节课我们学了 string 的基础:拼接、搜索、替换、大小写转换。
今天继续进阶——学习如何"切割"字符串(提取子串),以及一个经典问题:回文判断!
最后,我们用综合题来验证这两节课学到的所有 string 技能!
s.find("abc") 找不到时返回什么?(string::npos)s 全部转成大写?(for 循环 + toupper)假设你有一个身份证号码字符串:"110105199001234567"
你想从中提取出生年月日(第7到第14位),怎么做?
用 s.substr(6, 8) 就能一次搞定!
(下标从0开始,第7位就是下标6)
✨ 这就是 substr 的魔力——精准"切割"字符串的任意一段!
string s = "hello world";
// 格式1:s.substr(pos, len) — 从 pos 开始,截取 len 个字符
string sub1 = s.substr(0, 5); // "hello"
string sub2 = s.substr(6, 5); // "world"
// 格式2:s.substr(pos) — 从 pos 开始截到末尾
string sub3 = s.substr(6); // "world"
string date = "2024-03-15";
string year = date.substr(0, 4); // "2024"
string month = date.substr(5, 2); // "03"
string day = date.substr(8, 2); // "15"
⚠️ 注意:pos 超出字符串长度会报错!使用前要确认 pos < s.size()。
string s = "racecar";
int l = 0, r = s.size() - 1;
bool isOk = true;
while (l < r) {
if (s[l] != s[r]) {
isOk = false;
break;
}
l++; r--;
}
cout << (isOk ? "YES" : "NO") << endl;
🔍 双指针原理:分别从字符串的两端向中间移动,比较对应位置的字符是否相同。
string s = "racecar";
string rev = s;
reverse(rev.begin(), rev.end()); // 需要 #include <algorithm>
cout << (s == rev ? "YES" : "NO") << endl;
💡 reverse(s.begin(), s.end()) 可以直接将 string 原地逆序!
string 支持 C++ 标准库算法,可以使用迭代器范围:
#include <algorithm>
string s = "hello";
reverse(s.begin(), s.end()); // s = "olleh"
sort(s.begin(), s.end()); // s = "ehllo"(排序字符)
sort() - 排序reverse() - 逆序find() - 查找count() - 计数replace() - 替换transform() - 转换string s = "a1b2c3";
string result = "";
for (char c : s) {
if (!isdigit(c)) result += c; // 只保留非数字
}
// result = "abc"
思路:分割 → 反转每个单词 → 重新拼接
string line = "hello world";
// 使用字符串流分割单词
istringstream ss(line);
string word;
while (ss >> word) {
reverse(word.begin(), word.end());
// ... 重新拼接
}
string s = "abcdef"; cout << s.substr(2, 3); 的输出是?
答案:C | 解析:从下标 2(字符 'c')开始,截取 3 个字符:"cde"。
判断回文串,可以将字符串逆序后与原字符串比较,相同则是回文。( )
✓(正确)
输入字符串 s 和两个整数 l、r(1-indexed),输出 s 的第 l 到第 r 个字符(含边界)。
第一行字符串 s(不含空格)
第二行两整数 l r
提取的子串
输入:
helloworld 2 6
输出:
ellow
输入一个字符串,判断它是否是回文串(忽略大小写)。
一行字符串(不含空格,长度 ≤ 1000)
YES 或 NO
Racecar
YES
给定一个字符串 s(只含小写字母),求其中最长的回文子串。如有多个长度相同的,输出字典序最小的。
一行字符串 s(长度 ≤ 500)
最长回文子串
样例输入: babad
样例输出: aba
枚举所有起始位置 i 和长度 len,提取子串,判断是否回文。
时间复杂度 O(n²),对 n≤1000 的字符串完全足够。
s.substr(pos, len)
精准提取子串
reverse()
原地逆序
✨ 这两节课加起来,string 的重要操作已经全部掌握!
下节课开始进入全新主题:算法篇
从"枚举算法"开始,学习信息学竞赛的思维方法!
输入一个 URL,提取其中的域名(在 "://" 之后到 "/" 或末尾之前)。
样例: https://www.example.com/page → www.example.com
输入字符串 s 和整数 k,将 s 向左旋转 k 位(前 k 字符移到末尾)。
样例: abcde, 2 → cdeab
输入字符串 s,统计其中长度 ≥ 2 的回文子串的数量。
样例: aaa → 3("aa"×2 + "aaa"×1)