⌨ 知识库 string字符串操作与反转函数课堂讲义 1. 掌握C++中`string`类的常用操作(构造、访问、修改、搜索) 2. 理解双指针算法实现字符串反转的逻辑 3. 学会运用字符串操作解决实际问题(回文判断、单词反转、子串提取等) 分类 C++ 难度 基础 阅读 4 分钟 浏览 15 更新 2026-7-16 9:35:11 🌐 所有人可见 登录后记录进度 导出 MD 复制链接 打印 / PDF ## 一、课程目标 1. 掌握C++中`string`类的常用操作(构造、访问、修改、搜索) 2. 理解双指针算法实现字符串反转的逻辑 3. 学会运用字符串操作解决实际问题(回文判断、单词反转、子串提取等) ## 二、核心知识点 ### 1. `size_t` 数据类型 **定义**:C/C++中表示**无符号整数**的类型,用于安全表示对象大小(如字符串长度、数组索引) **特点**: • 定义在`<cstddef>`头文件中 • 实际类型依赖平台(32位为`unsigned int`,64位为`unsigned long long`) • 避免负数索引错误(与负数比较时会隐式转换为无符号数) **应用场景**: • `string::size()` • `vector::size()`等返回值类型 ### 2. `string` 构造函数与析构函数 | 函数声明 | 功能描述 | 示例代码 | | --- | --- | --- | | `string()` | 创建空字符串 | `string str1;` | | `string(const char* s)` | 用C风格字符串初始化 | `string str2("Hello");` | | `string(size_t n, char c)` | 创建包含`n`个字符`c`的字符串 | `string str3(5, 'A');` | | `~string()` | 释放对象资源(自动调用) | - | **示例**: ```cpp #include <iostream> #include <string> using namespace std; int main() { string empty_str; // 空字符串 string c_str("C++"); // 初始化自C字符串 string char_str(3, 'x'); // "xxx" cout << c_str << endl; // 输出:C++ return 0; } ``` ### 3. 基础操作函数 | 函数声明 | 功能描述 | 示例代码 | | --- | --- | --- | | `size_t size() const` | 返回字符串长度 | `cout << "Hello".size();` | | `bool empty() const` | 判断字符串是否为空 | `if (str.empty()) ...` | | `void clear()` | 清空字符串内容 | `str.clear();` | **示例**: ```cpp string s = "World"; cout << s.size(); // 输出:5 s.clear(); // s变为空字符串 ``` ### 题目一 **题目描述**: 编写一个 C++ 程序,定义一个 `string` 类型的字符串变量。利用 `size()` 函数获取字符串长度,通过 `for` 循环和下标的方式遍历字符串。在循环中,使用 if 语句根据字符的类型(大写字母、小写字母、数字、其他字符)进行分类统计,并输出每类字符的数量。 **输出示例:** ```plain 大写字母数量: 2 小写字母数量: 8 数字数量: 3 其他字符数量: 2 ``` **参考代码**: ```cpp #include <iostream> #include <string> using namespace std; int main() { string str = "Hello123! World"; int upperCount = 0, lowerCount = 0, digitCount = 0, otherCount = 0; size_t len = str.size(); for (size_t i = 0; i < len; ++i) { char ch = str[i]; if ('A' <= ch && ch <= 'Z') { upperCount++; } else if ('a' <= ch && ch <= 'z') { lowerCount++; } else if ('0' <= ch && ch <= '9') { digitCount++; } else { otherCount++; } } cout << "大写字母数量: " << upperCount << endl; cout << "小写字母数量: " << lowerCount << endl; cout << "数字数量: " << digitCount << endl; cout << "其他字符数量: " << otherCount << endl; return 0; } ``` ### 题目二 **题目描述**: 编写一个 C++ 程序,定义一个 `string` 类型的字符串变量。先使用 `empty()` 函数判断字符串是否为空,如果不为空,再使用 `for` 循环和下标的方式遍历字符串。在循环中,当遇到特定字符(比如 'e')时,使用 `if` 语句执行特殊操作(比如输出提示信息“遇到特殊字符”),最后使用 `clear()` 函数清空字符串,并再次使用 `empty()` 函数判断字符串是否为空并输出结果。 **输出示例:** ```plain 遇到特殊字符 字符串已成功清空 ``` **参考代码**: ```cpp #include <iostream> #include <string> using namespace std; int main() { string str = "Hello world"; if (!str.empty()) { size_t len = str.size(); for (size_t i = 0; i < len; ++i) { char ch = str[i]; if (ch == 'e') { cout << "遇到特殊字符" << endl; } } } str.clear(); if (str.empty()) { cout << "字符串已成功清空" << endl; } return 0; } ``` ### 4. 元素访问函数 | 函数声明 | 功能描述 | 区别 | | --- | --- | --- | | `char& operator[](size_t pos)` | 直接访问字符(无越界检查) | 越界会导致未定义行为 | | `char& at(size_t pos)` | 访问字符(带越界检查) | 安全性更高 | **示例**: ```cpp string s = "Hello"; s[0] = 'h'; // 修改首字符为'h' cout << s.at(1); // 输出'e' ``` ### 5. 字符串修改函数 | 函数声明 | 功能描述 | 示例代码 | | --- | --- | --- | | `string& append(const string& str)` | 追加字符串到末尾 | `s.append("!");` | | `string& insert(size_t pos, const string& str)` | 在位置`pos`插入字符串 | `s.insert(5, " World");` | | `string& erase(size_t pos = 0, size_t len = npos)` | 删除指定位置的字符 | `s.erase(0, 1);` | **示例**: ```cpp string s = "Hello"; s += " World"; // 等价于append s.insert(5, "!"); // 结果:"Hello! World" s.erase(6, 2); // 结果:"HelloWorld" ``` ### 题目一 题目描述: 已知有一个 `string` 类型的字符串 `s`,初始值为 `"Hello"`。请使用 `append` 函数在字符串末尾添加 `" World"`,然后使用 `insert` 函数在索引为 6 的位置插入一个感叹号 `"!"`,最后输出修改后的字符串。 输出示例: ```plain Hello! World ``` 参考代码: ```cpp #include <iostream> #include <string> using namespace std; int main() { string s = "Hello"; s.append(" World"); s.insert(6, "!"); cout << s << endl; return 0; } ``` --- ### 题目二 题目描述: 给定一个 `string` 类型的字符串 `s`,初始值为 `"Goodbye123"`。请使用 `erase` 函数删除字符串中索引从 3 开始、长度为 3 的子串,然后使用 `append` 函数在字符串末尾添加 `" Bye"`,最后输出修改后的字符串。 输出示例: ```plain Good Bye ``` 参考代码: ```cpp #include <iostream> #include <string> using namespace std; int main() { string s = "Goodbye123"; s.erase(3, 3); s.append(" Bye"); cout << s << endl; return 0; } ``` --- 这样调整后,读者可以先看到预期输出,再参考代码实现,逻辑更流畅。😊 ### 6. 搜索与子串函数 | 函数声明 | 功能描述 | 示例代码 | | --- | --- | --- | | `size_t find(const string& str)` | 查找子串位置 | `size_t pos = s.find("World");` | | `string substr(size_t pos, size_t len)` | 提取子串 | `string sub = s.substr(6, 5);` | **示例**: ```cpp string s = "Hello World"; if (s.find("World") != string::npos) { cout << "找到子串!"; } string sub = s.substr(0, 5); // "Hello" ``` ### 7. 反转字符串函数 #### 函数声明 ```cpp string reverse(const string& str); ``` #### 实现思路(双指针法) 1. 创建`result`拷贝原字符串 2. 使用左指针`left`和右指针`right` 3. 交换字符并向中间移动指针 #### 代码实现 ```cpp #include <iostream> #include <string> using namespace std; string reverse(const string& str) { string result = str; int left = 0, right = str.size() - 1; while (left < right) { swap(result[left], result[right]); left++; right--; } return result; } int main() { string s = "Hello"; cout << reverse(s) << endl; // 输出:olleH return 0; } ``` ## 三、综合示例 ```cpp #include <iostream> #include <string> using namespace std; int main() { string s = "C++"; s.append(" is powerful"); cout << s.substr(0, 3) << endl; // 输出:C++ return 0; } ``` ## 四、关键注意事项 1. `size_t`**的无符号特性**:避免与负数直接比较 2. **越界检查**:`at()`会抛异常,`operator[]`不检查越界 3. `string::npos`:表示无效位置(通常为`0xffffffff`) ## 五、练习题 ### 题目一:判断回文串 **要求**:输入字符串,判断是否为回文串 **示例**: • 输入`"radar"` → 输出"是回文串" • 输入`"hello"` → 输出"不是回文串" ### 题目二:反转每个单词 **要求**:输入字符串,反转每个单词 **示例**: • 输入`"Hello World"` → 输出`"olleH dlroW"` ### 题目三:提取并反转长单词 **要求**:提取长度>3的单词并反转 **示例**: • 输入`"The quick brown fox"` → 输出`"kciuq nworb"` ### 题目四:判断反转字符串 **要求**:判断第二个字符串是否是第一个的反转 **示例**: • 输入`"hello"`和`"olleh"` → 输出"是反转字符串" ## 六、扩展思考 如何优化`reverse`函数的空间复杂度?(提示:原地反转) 以下是各练习题的参考答案及解析: --- ## 五、练习题答案 ### 题目一:判断回文串 ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; bool isPalindrome(const string& s) { string reversed = s; reverse(reversed.begin(), reversed.end()); return s == reversed; } int main() { string input; cout << "输入字符串: "; getline(cin, input); if (isPalindrome(input)) { cout << "是回文串" << endl; } else { cout << "不是回文串" << endl; } return 0; } ``` **解析**:直接使用STL的`reverse`算法反转字符串后与原字符串比较。 --- ### 题目二:反转每个单词 ```cpp #include <iostream> #include <string> #include <sstream> #include <algorithm> using namespace std; string reverseWords(string s) { istringstream iss(s); string word, result; while (iss >> word) { reverse(word.begin(), word.end()); result += word + " "; } if (!result.empty()) { result.pop_back(); // 移除末尾多余空格 } return result; } int main() { string input; cout << "输入字符串: "; getline(cin, input); cout << reverseWords(input) << endl; return 0; } ``` **解析**:使用`istringstream`分割单词,对每个单词单独反转后重新拼接。 --- ### 题目三:提取并反转长单词 ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; int main() { string s = "The quick brown fox"; // 输入的原始字符串 string res; // 存储处理后的结果字符串 size_t pos = 0; // 记录当前查找单词的起始位置 while (true) { size_t sp = s.find(' ', pos); // 查找从pos位置开始的第一个空格的位置 if (sp == string::npos) { // 如果没找到空格,说明到了字符串末尾 string w = s.substr(pos); // 获取最后一个单词 if (w.size() > 3) { // 判断单词长度是否大于3 reverse(w.begin(), w.end()); // 反转单词 } res += w; // 将处理后的单词添加到结果字符串 break; } string w = s.substr(pos, sp - pos); // 获取当前单词 if (w.size() > 3) { // 判断单词长度是否大于3 reverse(w.begin(), w.end()); // 反转单词 } res += w + " "; // 将处理后的单词添加到结果字符串,并加上空格 pos = sp + 1; // 更新下一次查找单词的起始位置 } cout << res << endl; // 输出处理后的结果字符串 return 0; } ``` **解析**:在题目二基础上增加`word.size() > 3`的条件判断。 --- ### 题目四:判断反转字符串 ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; bool isReversed(const string& s1, const string& s2) { if (s1.size() != s2.size()) return false; string reversed = s1; reverse(reversed.begin(), reversed.end()); return reversed == s2; } int main() { string s1, s2; cout << "输入字符串1: "; getline(cin, s1); cout << "输入字符串2: "; getline(cin, s2); if (isReversed(s1, s2)) { cout << "是反转字符串" << endl; } else { cout << "不是反转字符串" << endl; } return 0; } ``` **解析**:先比较长度,再反转其中一个字符串后比较。 --- ## 六、扩展思考答案 **原地反转优化方案**: ```cpp void reverseInPlace(string& s) { int left = 0, right = s.size() - 1; while (left < right) { swap(s[left++], s[right--]); } } ``` **关键点**: 1. 直接修改输入字符串(需移除`const`限定) 2. 空间复杂度从O(n)优化到O(1) 3. 注意函数签名需改为非`const`引用参数:`void reverseInPlace(string& s)` 学习交流公开阅读不需要登录登录后可以评论、收藏并同步学习进度。登录暂时还没有评论。
学习交流