- C++
C++字符串处理入门教程:从基础到实战
- 2025-8-2 21:08:36 @
C++字符串处理入门教程:从基础到实战
字符串是编程中最常用的数据类型之一,尤其在处理文本、字符序列时更是不可或缺。本教程将围绕NOI编程基础中的字符串题目,从基础概念到实战案例,带你掌握C++字符串处理的核心技能。
一、C++字符串基础
1. 什么是字符串?
字符串是由零个或多个字符组成的有限序列。在C++中,我们通常使用string
类来处理字符串,它比传统的字符数组更易用、更安全。
2. 字符串的定义与初始化
#include <iostream>
#include <string> // 使用string类需要包含此头文件
using namespace std;
int main() {
// 定义字符串的几种方式
string s1; // 空字符串
string s2 = "hello"; // 直接初始化
string s3("world"); // 构造函数初始化
string s4(5, 'a'); // 重复字符初始化,结果是"aaaaa"
cout << s2 << " " << s3 << endl; // 输出:hello world
return 0;
}
3. 字符串的输入输出
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1, s2;
// cin输入:遇到空格或换行停止
cout << "请输入两个单词:";
cin >> s1 >> s2;
cout << "你输入的是:" << s1 << " " << s2 << endl;
// getline输入:读取一整行(包括空格)
cin.ignore(); // 清除输入缓冲区的换行符
cout << "请输入一句话:";
getline(cin, s1);
cout << "你输入的是:" << s1 << endl;
return 0;
}
注意:当
cin
和getline
混合使用时,需要用cin.ignore()
清除缓冲区中的换行符,否则getline
可能会读取到空行。
4. 字符串的基本操作
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "hello";
// 获取字符串长度
cout << "长度:" << s.size() << endl; // 输出:5
cout << "长度:" << s.length() << endl; // 输出:5(与size()功能相同)
// 字符串拼接
s += " world";
cout << "拼接后:" << s << endl; // 输出:hello world
// 字符串比较(与字典序比较相同)
string a = "apple", b = "banana";
if (a < b) {
cout << a << " 在 " << b << " 前面" << endl;
}
// 访问字符串中的字符
for (int i = 0; i < s.size(); i++) {
cout << s[i] << " "; // 逐个输出字符
}
cout << endl;
return 0;
}
二、字符串处理实战案例
案例1:基因相关性判断
题目描述:比较两条DNA序列的相关性,计算相同碱基对占总碱基对数量的比例,若大于等于阈值则判定相关。
#include<iostream>
#include<string>
using namespace std;
int main() {
double threshold; // 阈值
string a, b; // 两条DNA序列
// 输入阈值
cin >> threshold;
// 注意:cin后需要处理换行符
cin.ignore(); // 清除输入缓冲区的换行符
// 输入两条DNA序列
getline(cin, a);
getline(cin, b);
int same_count = 0; // 相同碱基对的数量
// 遍历两条序列,统计相同碱基对
for (int i = 0; i < a.size(); i++) {
if (a[i] == b[i]) { // 比较对应位置的碱基
same_count++;
}
}
// 计算比例并判断
double ratio = 1.0 * same_count / a.size();
if (ratio >= threshold) {
cout << "yes" << endl;
} else {
cout << "no" << endl;
}
return 0;
}
代码解析:
- 关键在于正确处理输入:先输入阈值(数值),再输入两行字符串
- 计算比例时需注意整数除法的问题,用
1.0 *
将结果转换为浮点数 - 通过循环遍历两个字符串的每个字符,比较并计数相同的碱基对
案例2:石头剪刀布游戏判定
题目描述:根据两人的选择(石头、剪刀、布),判定每局的胜利者。
#include<iostream>
#include<string>
using namespace std;
int main() {
int n; // 游戏次数
cin >> n;
// 处理n局游戏
for (int i = 0; i < n; i++) {
string p1, p2; // 玩家1和玩家2的选择
cin >> p1 >> p2;
// 判断胜负情况
if (p1 == p2) {
// 选择相同,平局
cout << "Tie" << endl;
}
// 玩家1获胜的情况
else if ((p1 == "Rock" && p2 == "Scissors") ||
(p1 == "Paper" && p2 == "Rock") ||
(p1 == "Scissors" && p2 == "Paper")) {
cout << "Player1" << endl;
}
// 其他情况都是玩家2获胜
else {
cout << "Player2" << endl;
}
}
return 0;
}
代码解析:
- 使用循环处理多局游戏
- 通过多条件判断语句覆盖所有可能的情况
- 逻辑清晰:先判断平局,再判断玩家1获胜的情况,其余则为玩家2获胜
案例3:输出亲朋字符串
题目描述:将字符串转换为亲朋字符串,规则是:每个字符为原字符串中相邻两个字符的ASCII值之和,最后一个字符为最后一个字符与第一个字符的ASCII值之和。
#include<iostream>
#include<string>
using namespace std;
int main() {
string str;
// 读取输入字符串(可能包含空格,所以用getline)
getline(cin, str);
string result = ""; // 存储结果
int len = str.size(); // 字符串长度
// 处理前len-1个字符
for (int i = 0; i < len - 1; i++) {
// 计算当前字符与下一个字符的ASCII值之和,转换为字符
char c = str[i] + str[i + 1];
result += c; // 添加到结果字符串
}
// 处理最后一个字符:最后一个字符与第一个字符的ASCII值之和
char last = str[len - 1] + str[0];
result += last;
// 输出结果
cout << result << endl;
return 0;
}
代码解析:
- 利用字符的ASCII值进行计算,直接相加即可得到新字符的ASCII值
- 注意循环的边界条件:处理到倒数第二个字符
- 单独处理最后一个特殊字符
案例4:配对碱基链
题目描述:根据DNA单链的碱基序列,输出其互补链(A与T配对,G与C配对)。
#include<iostream>
#include<string>
using namespace std;
int main() {
string dna;
// 读取输入的碱基链
cin >> dna;
// 遍历每个碱基,输出其互补碱基
for (int i = 0; i < dna.size(); i++) {
switch (dna[i]) {
case 'A': // A与T配对
cout << 'T';
break;
case 'T': // T与A配对
cout << 'A';
break;
case 'G': // G与C配对
cout << 'C';
break;
case 'C': // C与G配对
cout << 'G';
break;
}
}
cout << endl;
return 0;
}
代码解析:
- 使用switch语句处理四种碱基的配对关系
- 也可以使用if-else语句实现相同功能
- 逐个处理每个字符并输出结果,无需额外存储整个结果字符串
案例5:字符替换
题目描述:将字符串中所有指定的字符替换为另一个给定的字符。
#include<iostream>
#include<string>
using namespace std;
int main() {
string str;
char old_char, new_char;
// 输入字符串、被替换字符、替换字符
cin >> str >> old_char >> new_char;
// 遍历字符串,替换指定字符
for (int i = 0; i < str.size(); i++) {
if (str[i] == old_char) {
// 如果当前字符是要替换的字符,则输出新字符
cout << new_char;
} else {
// 否则输出原字符
cout << str[i];
}
}
cout << endl;
return 0;
}
代码解析:
- 遍历字符串中的每个字符,判断是否需要替换
- 可以直接输出结果,也可以先构建新字符串再输出
- 注意输入格式:三个参数之间用空格分隔
三、字符串处理常见技巧
-
字符与ASCII码转换
char c = 'A'; int ascii = c; // 得到ASCII码值65 char new_c = ascii + 32; // 转换为小写字母'a'
-
大小写转换
// 大写转小写:加32 char lower_c = upper_c + 32; // 小写转大写:减32 char upper_c = lower_c - 32; // 更通用的方法(使用cctype库) #include <cctype> char lower_c = tolower(upper_c); char upper_c = toupper(lower_c);
-
字符串遍历方法
// 方法1:下标遍历 for (int i = 0; i < str.size(); i++) { cout << str[i]; } // 方法2:范围for循环(C++11及以上) for (char c : str) { cout << c; }
-
字符串查找与替换
// 查找子串 string str = "hello world"; size_t pos = str.find("world"); // 查找"world"的位置 if (pos != string::npos) { cout << "找到子串,位置:" << pos << endl; } // 替换子串 str.replace(pos, 5, "there"); // 从pos位置开始,替换5个字符为"there" cout << str << endl; // 输出:hello there
四、练习题推荐
根据难度递增,推荐以下练习题:
-
★ 基础题
- 统计数字字符个数:遍历字符串,统计0-9的字符数量
- 小写转大写:将字符串中所有小写字母转为大写
-
★☆ 进阶题
- 找第一个只出现一次的字符:记录每个字符出现次数,找到第一个次数为1的字符
- 字符串判等:判断两个字符串是否完全相同
-
★★ 挑战题
- 密码翻译:实现凯撒密码,将字母按指定位数偏移
- 验证子串:判断一个字符串是否是另一个字符串的子串
通过这些练习,你可以逐步掌握C++字符串处理的各种技巧,为更复杂的编程问题打下基础。记住,编程能力的提升离不开大量的实践,多写多练才能熟练掌握这些知识。
0 条评论
目前还没有评论...