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

文章目录

一.C++字符串基础操作

1.声明与初始化

cpp 复制代码
#include <iostream>
#include <string>

int main() {
    // 声明一个空字符串
    std::string str1;

    // 声明并初始化为一个常量字符串
    std::string str2 = "Hello";

    // 使用构造函数初始化
    std::string str3("World");

    // 用另一个字符串初始化
    std::string str4(str2); 

    return 0;
}

2.输入输出

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int main() {
    // 读单个单词(遇到空格停止)
    string s1;
    cin >> s1; 

    // 读整行(包括空格)
    string s2;
    cin.ignore(); // 清除之前的换行符
    getline(cin, s2);

    // 输出
    cout << s1 << endl << s2;
}

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::ostringstream
  • 查找与替换 :熟悉 find()rfind() 查找子串位置,以及 replace() 替换子串。在处理文本匹配、修改等问题时能迅速运用这些方法。
cpp 复制代码
std::string text = "Hello World";
size_t pos = text.find("World");
if (pos != std::string::npos) {
    text.replace(pos, 5, "Universe");
}
  • 截取 :掌握 substr() 方法截取子串,在需要提取部分字符串信息时很有用。
cpp 复制代码
std::string str = "abcdef";
std::string sub = str.substr(1, 3);  // 从位置 1 开始截取长度为 3 的子串

3.易错点

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

【代码实例】

cpp 复制代码
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    int x = 566;
    string str = to_string(x);
    cout << str << endl;
    cout << str[0] << endl;
    return 0;
}
//输出:566
//5

二.C++高频算法实现

1.KMP算法

cpp 复制代码
// 构建next数组
vector<int> buildNext(const string& pattern) {
    int n = pattern.size();
    vector<int> next(n, 0);
    for (int i = 1, j = 0; i < n; i++) {
        while (j > 0 && pattern[i] != pattern[j]) j = next[j-1];
        if (pattern[i] == pattern[j]) j++;
        next[i] = j;
    }
    return next;
}

// 匹配过程
int kmp(const string& text, const string& pattern) {
    vector<int> next = buildNext(pattern);
    int j = 0;
    for (int i = 0; i < text.size(); i++) {
        while (j > 0 && text[i] != pattern[j]) j = next[j-1];
        if (text[i] == pattern[j]) j++;
        if (j == pattern.size()) return i - j + 1; // 返回首次匹配的起始位置
    }
    return -1;
}

2.最长回文子串(Manacher算法)

cpp 复制代码
string longestPalindrome(string s) {
    string t = "#";
    for (char c : s) { t += c; t += '#'; } // 插入特殊字符处理奇偶长度
    int n = t.size(), center = 0, maxRight = 0, maxLen = 0, start = 0;
    vector<int> p(n, 0);
    
    for (int i = 0; i < n; i++) {
        int mirror = 2 * center - i;
        if (i < maxRight) p[i] = min(maxRight - i, p[mirror]);
        int l = i - p[i] - 1, r = i + p[i] + 1;
        while (l >= 0 && r < n && t[l] == t[r]) { p[i]++; l--; r++; }
        if (i + p[i] > maxRight) { maxRight = i + p[i]; center = i; }
        if (p[i] > maxLen) { maxLen = p[i]; start = (i - p[i]) / 2; }
    }
    return s.substr(start, maxLen);
}

3.字符串分割

cpp 复制代码
vector<string> split(const string& s, char delimiter) {
    vector<string> tokens;
    string token;
    for (char c : s) {
        if (c != delimiter) token += c;
        else { if (!token.empty()) tokens.push_back(token); token.clear(); }
    }
    if (!token.empty()) tokens.push_back(token);
    return tokens;
}

4.与排序算法结合

当需要对字符串数组进行排序时,可利用标准库的 std::sort 函数,结合自定义比较函数实现特定排序规则。比如按字符串长度排序、按字典序逆序排序等。【参考洛谷排序算法题】

cpp 复制代码
#include <algorithm>
#include <vector>
bool compareByLength(const std::string& a, const std::string& b) {
    return a.length() < b.length();
}
std::vector<std::string> strs = {"apple", "banana", "pear"};
std::sort(strs.begin(), strs.end(), compareByLength);

三.经典题型与C++实现

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

cpp 复制代码
bool isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

bool isValidDate(int y, int m, int d) {
    int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (isLeapYear(y)) days[2] = 29;
    return m >= 1 && m <= 12 && d >= 1 && d <= days[m];
}

bool isPalindromeDate(const string& date) {
    string reversed = date;
    reverse(reversed.begin(), reversed.end());
    if (date != reversed) return false;
    int year = stoi(date.substr(0, 4));
    int month = stoi(date.substr(4, 2));
    int day = stoi(date.substr(6, 2));
    return isValidDate(year, month, day);
}

2.单词逆序输出(天梯赛真题)

cpp 复制代码
string reverseWords(string s) {
    vector<string> words = split(s, ' ');
    reverse(words.begin(), words.end());
    string res;
    for (auto& word : words) {
        if (!res.empty()) res += " ";
        res += word;
    }
    return res;
}

四.优化技巧

1.减少内存分配

预分配空间 :已知字符串长度时,用 reserve 提前分配内存。

cpp 复制代码
string s;
s.reserve(1000); // 预分配1000字节

2.高效遍历

当传递 std::string 作为函数参数时,如果不需要修改字符串内容,尽量使用常量引用 const std::string&,减少不必要的复制开销。

使用引用避免拷贝

cpp 复制代码
void printString(const std::string& str) {
    std::cout << str << std::endl;
}

3.使用哈希表加速

在处理字符串计数、查找重复字符串等问题时,可使用 std::unordered_map 作为哈希表,提高查找和统计效率。

统计字符出现位置

cpp 复制代码
unordered_map<char, vector<int>> posMap;
for (int i = 0; i < s.size(); i++) {
    posMap[s[i]].push_back(i);
}
相关推荐
待bong1 小时前
蓝桥杯EDA客观题(自己收集的)
职场和发展·蓝桥杯
沉默-_-1 小时前
备战蓝桥杯-哈希
c++·学习·算法·蓝桥杯·哈希算法
曹牧1 小时前
Java Web:DispatcherServlet
java·开发语言·前端
hehelm1 小时前
C++ 模拟实现 AVL 树
开发语言·c++
李日灐1 小时前
< 7 > Linux 开发工具:git 版本控制器 和 cgdb/gdb 调试器
linux·运维·服务器·开发语言·git·调试器·gdb/cgdb
会编程的土豆1 小时前
洛谷题单 入门1 顺序结构(go语言)
开发语言·后端·golang·洛谷
jieyucx1 小时前
Go 语言 switch 条件语句详解
开发语言·c++·golang
AC赳赳老秦2 小时前
网安工程师提效:用 OpenClaw 实现漏洞扫描报告生成、安全巡检自动化、日志合规审计
java·开发语言·前端·javascript·python·deepseek·openclaw
初心未改HD2 小时前
Go语言defer机制深度解析
开发语言·golang