【STL】蓝桥杯/天梯赛终极杀器!10个C++字符串核心本领,暴力破解高频考点 ...

打印 上一主题 下一主题

主题 1855|帖子 1855|积分 5565

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一.C++字符串根本操作

1.声明与初始化
  1. #include <iostream>
  2. #include <string>
  3. int main() {
  4.     // 声明一个空字符串
  5.     std::string str1;
  6.     // 声明并初始化为一个常量字符串
  7.     std::string str2 = "Hello";
  8.     // 使用构造函数初始化
  9.     std::string str3("World");
  10.     // 用另一个字符串初始化
  11.     std::string str4(str2);
  12.     return 0;
  13. }
复制代码
2.输入输出
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main() {
  5.     // 读单个单词(遇到空格停止)
  6.     string s1;
  7.     cin >> s1;
  8.     // 读整行(包括空格)
  9.     string s2;
  10.     cin.ignore(); // 清除之前的换行符
  11.     getline(cin, s2);
  12.     // 输出
  13.     cout << s1 << endl << s2;
  14. }
复制代码
2.常用成员函数
操作代码示例分析长度int len = s.length();等价于 s.size()拼接string s3 = s1 + s2;直接使用 + 运算符子串string sub = s.substr(2, 5);从索引2开始,取5个字符(若超出范围会截断)查找字符int pos = s.find("abc");返回初次出现的位置,若未找到返回 string::npos(通常为4294967295)替换s.replace(2, 3, "xxx");从索引2开始替换3个字符为"xxx"插入s.insert(3, "xyz");在索引3处插入"xyz"删除s.erase(2, 4);从索引2开始删除4个字符清空s.clear();清空字符串比较str1.compare(str2)逐个字符按照ASCII码大小进行比较 详细操作参考string操作
注意:


  • 拼接:机动运用 + 运算符和 append() 方法进行字符串拼接。比方,在处理多个字符勾通接成一个大字符串的场景时,要清楚它们的性能差异,一般少量拼接用 + 简洁直观,大量拼接可考虑 append() 或 std:stringstream。


  • 查找与替换:熟悉 find()、rfind() 查找子串位置,以及 replace() 替换子串。在处理文本匹配、修改等题目时能敏捷运用这些方法。
  1. std::string text = "Hello World";
  2. size_t pos = text.find("World");
  3. if (pos != std::string::npos) {
  4.     text.replace(pos, 5, "Universe");
  5. }
复制代码


  • 截取:掌握 substr() 方法截取子串,在必要提取部分字符串信息时很有效。
  1. std::string str = "abcdef";
  2. std::string sub = str.substr(1, 3);  // 从位置 1 开始截取长度为 3 的子串
复制代码
3.易错点


  • 性能题目:std::string 的拼接操作可能会带来性能开销,尤其是在循环中频仍拼接时。可以考虑使用 std:stringstream 来提高性能。但是这种做法可能会引入定名辩论的风险,以是在大型项目中建议尽量明确指定定名空间。
  • 索引越界:访问 s[s.length()] 会导致未定义行为(正当索引为 0~s.length()-1)。
  • 混合输入题目:cin 后直接使用 getline 会读到空字符串,需先用 cin.ignore() 清空缓冲区。
  • 字符转数值
  1. char c = 'A';
  2. int num = c - '0';      // 错误!'A'的ASCII码是65,得到65-48=17
  3. int hex = c >= 'A' ? (c - 'A' + 10) : (c - '0'); // 正确处理十六进制字符
复制代码


  • to_string数字常量转字符串
    头文件:#include < cstring> 或 #include <string.h>。参数的范例可以是int,long,double,long。例:
  1. stirng str = to_string(int x); //参数为int型数字常量
复制代码
【代码实例】
  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. int main()
  5. {
  6.     int x = 566;
  7.     string str = to_string(x);
  8.     cout << str << endl;
  9.     cout << str[0] << endl;
  10.     return 0;
  11. }
  12. //输出:566
  13. //5
复制代码
二.C++高频算法实现

1.KMP算法

  1. // 构建next数组
  2. vector<int> buildNext(const string& pattern) {
  3.     int n = pattern.size();
  4.     vector<int> next(n, 0);
  5.     for (int i = 1, j = 0; i < n; i++) {
  6.         while (j > 0 && pattern[i] != pattern[j]) j = next[j-1];
  7.         if (pattern[i] == pattern[j]) j++;
  8.         next[i] = j;
  9.     }
  10.     return next;
  11. }
  12. // 匹配过程
  13. int kmp(const string& text, const string& pattern) {
  14.     vector<int> next = buildNext(pattern);
  15.     int j = 0;
  16.     for (int i = 0; i < text.size(); i++) {
  17.         while (j > 0 && text[i] != pattern[j]) j = next[j-1];
  18.         if (text[i] == pattern[j]) j++;
  19.         if (j == pattern.size()) return i - j + 1; // 返回首次匹配的起始位置
  20.     }
  21.     return -1;
  22. }
复制代码
2.最长回文子串(Manacher算法)

  1. string longestPalindrome(string s) {
  2.     string t = "#";
  3.     for (char c : s) { t += c; t += '#'; } // 插入特殊字符处理奇偶长度
  4.     int n = t.size(), center = 0, maxRight = 0, maxLen = 0, start = 0;
  5.     vector<int> p(n, 0);
  6.    
  7.     for (int i = 0; i < n; i++) {
  8.         int mirror = 2 * center - i;
  9.         if (i < maxRight) p[i] = min(maxRight - i, p[mirror]);
  10.         int l = i - p[i] - 1, r = i + p[i] + 1;
  11.         while (l >= 0 && r < n && t[l] == t[r]) { p[i]++; l--; r++; }
  12.         if (i + p[i] > maxRight) { maxRight = i + p[i]; center = i; }
  13.         if (p[i] > maxLen) { maxLen = p[i]; start = (i - p[i]) / 2; }
  14.     }
  15.     return s.substr(start, maxLen);
  16. }
复制代码
3.字符串分割

  1. vector<string> split(const string& s, char delimiter) {
  2.     vector<string> tokens;
  3.     string token;
  4.     for (char c : s) {
  5.         if (c != delimiter) token += c;
  6.         else { if (!token.empty()) tokens.push_back(token); token.clear(); }
  7.     }
  8.     if (!token.empty()) tokens.push_back(token);
  9.     return tokens;
  10. }
复制代码
4.与排序算法结合

当必要对字符串数组进行排序时,可利用标准库的 std::sort 函数,结合自定义比较函数实现特定排序规则。比如按字符串长度排序、按字典序逆序排序等。【参考洛谷排序算法题】
  1. #include <algorithm>
  2. #include <vector>
  3. bool compareByLength(const std::string& a, const std::string& b) {
  4.     return a.length() < b.length();
  5. }
  6. std::vector<std::string> strs = {"apple", "banana", "pear"};
  7. std::sort(strs.begin(), strs.end(), compareByLength);
复制代码
三.经典题型与C++实现

1.回文日期验证(蓝桥杯真题)

  1. bool isLeapYear(int year) {
  2.     return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  3. }
  4. bool isValidDate(int y, int m, int d) {
  5.     int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  6.     if (isLeapYear(y)) days[2] = 29;
  7.     return m >= 1 && m <= 12 && d >= 1 && d <= days[m];
  8. }
  9. bool isPalindromeDate(const string& date) {
  10.     string reversed = date;
  11.     reverse(reversed.begin(), reversed.end());
  12.     if (date != reversed) return false;
  13.     int year = stoi(date.substr(0, 4));
  14.     int month = stoi(date.substr(4, 2));
  15.     int day = stoi(date.substr(6, 2));
  16.     return isValidDate(year, month, day);
  17. }
复制代码
2.单词逆序输出(天梯赛真题)

  1. string reverseWords(string s) {
  2.     vector<string> words = split(s, ' ');
  3.     reverse(words.begin(), words.end());
  4.     string res;
  5.     for (auto& word : words) {
  6.         if (!res.empty()) res += " ";
  7.         res += word;
  8.     }
  9.     return res;
  10. }
复制代码
四.优化本领

1.淘汰内存分配
预分配空间:已知字符串长度时,用 reserve 提前分配内存。
  1. string s;
  2. s.reserve(1000); // 预分配1000字节
复制代码
2.高效遍历
当通报 std::string 作为函数参数时,如果不必要修改字符串内容,尽量使用常量引用 const std::string&,淘汰不必要的复制开销。
使用引用制止拷贝
  1. void printString(const std::string& str) {
  2.     std::cout << str << std::endl;
  3. }
复制代码
3.使用哈希表加速
在处理字符串计数、查找重复字符串等题目时,可使用 std::unordered_map 作为哈希表,提高查找和统计效率。
统计字符出现位置
  1. unordered_map<char, vector<int>> posMap;
  2. for (int i = 0; i < s.size(); i++) {
  3.     posMap[s[i]].push_back(i);
  4. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表