qidao123.com技术社区-IT企服评测·应用市场
标题:
【STL】蓝桥杯/天梯赛终极杀器!10个C++字符串核心本领,暴力破解高频考点
[打印本页]
作者:
悠扬随风
时间:
2025-4-26 20:14
标题:
【STL】蓝桥杯/天梯赛终极杀器!10个C++字符串核心本领,暴力破解高频考点
一.C++字符串根本操作
1.声明与初始化
#include <iostream>
#include <string>
int main() {
// 声明一个空字符串
std::string str1;
// 声明并初始化为一个常量字符串
std::string str2 = "Hello";
// 使用构造函数初始化
std::string str3("World");
// 用另一个字符串初始化
std::string str4(str2);
return 0;
}
复制代码
2.输入输出
#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:
stringstream。
查找与替换
:熟悉 find()、rfind() 查找子串位置,以及 replace() 替换子串。在处理文本匹配、修改等题目时能敏捷运用这些方法。
std::string text = "Hello World";
size_t pos = text.find("World");
if (pos != std::string::npos) {
text.replace(pos, 5, "Universe");
}
复制代码
截取
:掌握 substr() 方法截取子串,在必要提取部分字符串信息时很有效。
std::string str = "abcdef";
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() 清空缓冲区。
字符转数值
:
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。例:
stirng str = to_string(int x); //参数为int型数字常量
复制代码
【代码实例】
#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算法
// 构建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算法)
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.字符串分割
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 函数,结合自定义比较函数实现特定排序规则。比如按字符串长度排序、按字典序逆序排序等。【参考洛谷排序算法题】
#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.回文日期验证(蓝桥杯真题)
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.单词逆序输出(天梯赛真题)
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 提前分配内存。
string s;
s.reserve(1000); // 预分配1000字节
复制代码
2.高效遍历
当通报 std::string 作为函数参数时,如果不必要修改字符串内容,尽量使用常量引用 const std::string&,淘汰不必要的复制开销。
使用引用制止拷贝
:
void printString(const std::string& str) {
std::cout << str << std::endl;
}
复制代码
3.使用哈希表加速
在处理字符串计数、查找重复字符串等题目时,可使用 std::unordered_map 作为哈希表,提高查找和统计效率。
统计字符出现位置
:
unordered_map<char, vector<int>> posMap;
for (int i = 0; i < s.size(); i++) {
posMap[s[i]].push_back(i);
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4