STL——洛谷字符串(string库)入门题(蓝桥杯题目训练)(一)
- 电脑硬件
- 2025-09-02 13:27:01

目录
一、B2109 统计数字字符个数 - 洛谷
算法代码:
1. 引入库和命名空间
2. 主函数
3. 读取输入
4. 变量初始化
5. 遍历字符串
6. 输出结果
7. 返回值
总结
评测记录:
二、B2110 找第一个只出现一次的字符 - 洛谷
方法一:算法代码(使用哈希表)
1. 引入库和命名空间
2. 定义首个唯一字符的函数
3. 处理空字符串
4. 统计字符出现次数
5. 找到第一个只出现一次的字符
6. 如果没有找到唯一字符
7. 主函数
总结
方法二:算法代码(使用数组实现哈希表)
1. 引入库和命名空间
2. 定义首个唯一字符的函数
3. 处理空字符串
4. 初始化字符计数数组
5. 统计字符出现次数
6. 找到第一个只出现一次的字符
7. 如果没有找到唯一字符
8. 主函数
总结
评测记录:
三、B2112 石头剪子布 - 洛谷
算法代码:
1. 引入库
2. 主函数
3. 读取输入
4. 循环处理每局游戏
5. 读取玩家的出手
6. 判断胜负
7. 判断玩家1的胜负情况
8. 返回值
总结
评测记录:
四、B2113 输出亲朋字符串 - 洛谷
算法代码:
1. 引入库和命名空间
2. 定义生成 Friend String 的函数
3. 初始化变量
4. 遍历字符串
5. 生成新字符
6. 添加新字符到结果字符串
7. 返回结果
8. 主函数
注意
代码改进建议
总结
评测记录:
五、B2114 配对碱基链 - 洛谷
方法一:算法代码(使用map一一对应)
1. 引入库
2. 定义全局变量
3. 主函数
4. 读取输入
5. 定义碱基配对关系
6. 输出互补序列
7. 返回值
总结
方法二:算法代码(直接替换)
1. 引入库
2. 定义字符数组
3. 主函数
4. 读取输入
5. 遍历字符串并转换碱基
6. 返回值
总结
改进建议
测评记录:
六、 B2116 加密的病历单 - 洛谷
算法代码:
1. 引入库
2. 定义解密函数
3. 初始化结果字符串
4. 步骤 1:大小写反转
5. 步骤 2:逆序存储
6. 步骤 3:字符循环右移三个位置
为什么使用模运算(% 26)
7. 返回结果
8. 主函数
总结
评测记录:
七、B2117 整理药名 - 洛谷
算法代码:
1. 引入必要的库
2. 定义主函数
3. 读取字符串数量
4. 循环处理每个字符串
5. 格式化首字母为大写
6. 格式化其他字符为小写
7. 输出格式化后的字符串
8. 结束主函数
完整代码示例
总结
评测记录:
八、B2118 验证子串 - 洛谷
算法代码:
1、代码思路:
2、代码解释:
3、代码优化建议:
4、优化后的代码:
5、优化点解释:
评测记录
九、B2119 删除单词后缀 - 洛谷
算法代码:
1、代码思路:
2、具体实现步骤:
评测记录:编辑
十、 B2120 单词的长度 - 洛谷
算法代码:
引入库
定义主函数
声明变量
循环读取输入
处理第一次输入
处理后续输入
结束主函数
总结
评测记录:
一、B2109 统计数字字符个数 - 洛谷 算法代码: #include<iostream> #include<string> using namespace std; int main() { string s; getline(cin,s); int num=0; int n=s.size(); for(int i=0;i<n;i++) { if(s[i]>='0'&&s[i]<='9') { num++; } else { continue; } } cout<<num<<endl; } 1. 引入库和命名空间 #include<iostream> #include<string> using namespace std;
#include <iostream>: 引入输入输出流库,用于处理输入和输出。
#include <string>: 引入字符串库,提供字符串处理功能。
using namespace std;: 允许直接使用 std 命名空间中的元素。
2. 主函数 int main() {主程序的入口。
3. 读取输入 string s; getline(cin, s);创建一个字符串 s。
使用 getline(cin, s) 从标准输入读取一整行,直到遇到换行符为止。
4. 变量初始化 int num = 0; int n = s.size();int num = 0;: 初始化计数器 num 为 0,用于统计数字字符的个数。
int n = s.size();: 获取字符串 s 的长度,用于后续的循环条件。
5. 遍历字符串 for(int i = 0; i < n; i++) { if(s[i] >= '0' && s[i] <= '9') { num++; } else { continue; } }使用 for 循环遍历字符串中的每个字符。
判断条件:
如果当前字符 s[i] 是数字(在 '0' 到 '9' 之间),则 num 增加 1。
如果当前字符不是数字,continue 语句将使循环继续到下一个字符,实际上这里的 continue 是可以省略的,因为后面没有其他代码了。
6. 输出结果 cout << num << endl;输出计数器 num,即字符串中数字字符的总数。
7. 返回值 return 0;返回 0,表示程序正常退出。
总结这段代码有效地统计了输入字符串中数字字符的个数,时间复杂度为 O(n),其中 n 是字符串的长度,因为每个字符都被访问了一次。代码简单直接,适合用来进行字符统计的基本操作。
评测记录: 二、B2110 找第一个只出现一次的字符 - 洛谷 方法一:算法代码(使用哈希表) #include <iostream> #include <unordered_map> using namespace std; string firstUniqueChar(const string& s) { if (s.empty()) { return "no"; // 处理空字符串 } unordered_map<char, int> charCount; // 统计每个字符的出现次数 for (char ch : s) { if (ch >= 'a' && ch <= 'z') { // 确保只处理小写字母 charCount[ch]++; } } // 找到第一个只出现一次的字符 for (char ch : s) { if (charCount[ch] == 1) { return string(1, ch); // 返回字符的字符串形式 } } // 如果没有找到,返回 "no" return "no"; } int main() { string s; cin >> s; string result = firstUniqueChar(s); cout << result << endl; return 0; } 1. 引入库和命名空间 #include <iostream> #include <unordered_map> using namespace std;#include <iostream>: 引入输入输出流库,用于处理输入和输出。
#include <unordered_map>: 引入哈希表(无序映射)库,以便使用 unordered_map 来存储字符及其出现次数。
using namespace std;: 允许直接使用 std 命名空间中的元素,避免在使用标准库函数时加上 std:: 前缀。
2. 定义首个唯一字符的函数 string firstUniqueChar(const string& s) {firstUniqueChar 函数接受一个常量字符串引用 s,返回一个字符串。
3. 处理空字符串 if (s.empty()) { return "no"; // 处理空字符串 }检查字符串是否为空。如果为空,则直接返回 "no"。
4. 统计字符出现次数 unordered_map<char, int> charCount; // 统计每个字符的出现次数 for (char ch : s) { if (ch >= 'a' && ch <= 'z') { // 确保只处理小写字母 charCount[ch]++; } }使用 unordered_map<char, int> 变量 charCount 来存储每个字符及其出现的次数。
遍历字符串 s,对于每个字符 ch:
仅当字符是小写字母(’a’ 到 'z’)时,才对其进行统计,使用 charCount[ch]++ 进行计数。
5. 找到第一个只出现一次的字符 for (char ch : s) { if (charCount[ch] == 1) { return string(1, ch); // 返回字符的字符串形式 } }再次遍历字符串 s,查找第一个只出现一次的字符:
如果 charCount[ch] == 1,则返回该字符的字符串形式(使用 string(1, ch) 将字符转换为字符串)。
6. 如果没有找到唯一字符 return "no";如果遍历结束后仍未找到任何只出现一次的字符,则返回 "no"。
7. 主函数 int main() { string s; cin >> s; string result = firstUniqueChar(s); cout << result << endl; return 0; }主函数中读取字符串 s,调用 firstUniqueChar 函数获取结果,并输出结果。
总结这段代码有效地找到了给定字符串中第一个只出现一次的字符,时间复杂度为 O(n),其中 n 是字符串的长度。使用 unordered_map 可以在 O(1) 时间内访问字符的计数。整体方法简单且高效,适合处理此类问题。
方法二:算法代码(使用数组实现哈希表) #include <iostream> #include <vector> using namespace std; string firstUniqueChar(const string& s) { if (s.empty()) { return "no"; // 处理空字符串 } vector<int> charCount(26, 0); // 初始化一个大小为26的数组,用于统计每个字母的出现次数 // 统计每个字符的出现次数 for (char ch : s) { if (ch >= 'a' && ch <= 'z') { // 确保只处理小写字母 charCount[ch - 'a']++; } } // 找到第一个只出现一次的字符 for (char ch : s) { if (ch >= 'a' && ch <= 'z' && charCount[ch - 'a'] == 1) { return string(1, ch); // 返回字符的字符串形式 } } // 如果没有找到,返回 "no" return "no"; } int main() { string s; cin >> s; string result = firstUniqueChar(s); cout << result << endl; return 0; } 1. 引入库和命名空间 #include <iostream> #include <vector> using namespace std;#include <iostream>: 引入输入输出流库,用于处理输入和输出。
#include <vector>: 引入向量库,使得可以使用 vector 容器。
using namespace std;: 允许直接使用 std 命名空间中的元素,避免在使用标准库函数时加上 std:: 前缀。
2. 定义首个唯一字符的函数 string firstUniqueChar(const string& s) {firstUniqueChar 函数接受一个常量字符串引用 s,返回一个字符串。
3. 处理空字符串 if (s.empty()) { return "no"; // 处理空字符串 }检查字符串是否为空。如果为空,则直接返回 "no"。
4. 初始化字符计数数组 vector<int> charCount(26, 0); // 初始化一个大小为26的数组,用于统计每个字母的出现次数创建一个大小为 26 的 vector<int> 数组 charCount,初始值都为 0。这个数组用于统计小写字母(’a’ 到 'z’)的出现次数。
5. 统计字符出现次数 for (char ch : s) { if (ch >= 'a' && ch <= 'z') { // 确保只处理小写字母 charCount[ch - 'a']++; } }遍历字符串 s,对于每个字符 ch:
仅当字符是小写字母(’a’ 到 ‘z’)时,才对其进行统计。通过 charCount[ch - 'a']++ 更新对应字母的计数。这里 ch - 'a' 转换字符到数组索引(例如,’a’ 对应 0,’b’ 对应 1,以此类推)。
6. 找到第一个只出现一次的字符 for (char ch : s) { if (ch >= 'a' && ch <= 'z' && charCount[ch - 'a'] == 1) { return string(1, ch); // 返回字符的字符串形式 } }再次遍历字符串 s,查找第一个只出现一次的字符:
如果字符是小写字母并且其计数为 1 (charCount[ch - 'a'] == 1),则返回该字符的字符串形式(使用 string(1, ch)将字符转换为字符串)。
7. 如果没有找到唯一字符 return "no";如果遍历结束后仍未找到任何只出现一次的字符,则返回 "no"。
8. 主函数 int main() { string s; cin >> s; string result = firstUniqueChar(s); cout << result << endl; return 0; }主函数中读取字符串 s,调用 firstUniqueChar 函数获取结果,并输出结果。
总结这段代码有效地找到了给定字符串中第一个只出现一次的字符,时间复杂度为 O(n),其中 n 是字符串的长度。通过使用一个大小固定的数组来存储字符的计数,简化了字符计数的实现,同时提高了空间效率。这种方法简单而高效,适合处理此类问题。
评测记录: 三、B2112 石头剪子布 - 洛谷 算法代码: #include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; for(int i=0; i<n; i++) { string a,b; cin>>a>>b;//读入两个字符串 if(a[0]==b[0])cout<<"Tie\n";//首位相同,平局 else if(a[0]=='R') { if(b[0]=='P')cout<<"Player2\n"; else cout<<"Player1\n"; } else if(a[0]=='P') { if(b[0]=='S')cout<<"Player2\n"; else cout<<"Player1\n"; } else if(a[0]=='S') { if(b[0]=='R')cout<<"Player2\n"; else cout<<"Player1\n"; }//以上是逐个判断,按照 Player1 的情况分类讨论 //因为讨论过平局了,可以只分两种情况考虑 //记得使用 else-if } return 0; } 1. 引入库 #include <bits/stdc++.h> using namespace std;#include <bits/stdc++.h>: 这是一个包含了大多数标准库的头文件,通常用于竞争性编程以减少代码的输入量。虽然在实际开发中不建议使用,但在比赛中常被使用。
2. 主函数 int main() {程序的主入口。
3. 读取输入 int n; cin >> n;读取一个整数 n,表示接下来要处理的对局数量。
4. 循环处理每局游戏 for (int i = 0; i < n; i++) {使用 for 循环遍历每一局游戏。
5. 读取玩家的出手 string a, b; cin >> a >> b; // 读入两个字符串为每局读取两个字符串 a 和 b,分别代表玩家1和玩家2的出手。
6. 判断胜负 if (a[0] == b[0]) cout << "Tie\n"; // 首位相同,平局如果玩家1和玩家2的出手相同(即两个字符串的第一个字符相同),则输出“平局”("Tie")。
7. 判断玩家1的胜负情况 else if (a[0] == 'R') { if (b[0] == 'P') cout << "Player2\n"; else cout << "Player1\n"; } else if (a[0] == 'P') { if (b[0] == 'S') cout << "Player2\n"; else cout << "Player1\n"; } else if (a[0] == 'S') { if (b[0] == 'R') cout << "Player2\n"; else cout << "Player1\n"; }对于玩家1的每种可能(’R’、’P’、’S’),使用 if-else 结构来判断其对应的输赢情况:
如果玩家1出的是 'R’(石头):
如果玩家2出的是 'P’(布),则玩家2胜(输出 "Player2")。
否则,玩家1胜。
如果玩家1出的是 'P’(布):
如果玩家2出的是 'S’(剪子),则玩家2胜。
否则,玩家1胜。
如果玩家1出的是 'S’(剪子):
如果玩家2出的是 'R’(石头),则玩家2胜。
否则,玩家1胜。
8. 返回值 return 0;返回 0,表示程序正常退出。
总结这段代码实现了一个简单的“石头、剪子、布”游戏的逻辑。它通过判断两个玩家的出手情况,输出胜负结果。代码结构清晰,使用了 if-else 语句来处理不同的情况,时间复杂度为 O(n),其中 n 是输入的局数。这种实现是符合石头剪子布游戏规则的典型示例。
评测记录: 四、B2113 输出亲朋字符串 - 洛谷 算法代码: #include <iostream> #include <string> using namespace std; string generateFriendString(const string& s) { string result; int n = s.length(); for (int i = 0; i < n; ++i) { char newChar; if (i < n - 1) { newChar = s[i] + s[i + 1]; } else { newChar = s[i] + s[0]; } result += newChar; } return result; } int main() { string inputStr; cin >> inputStr; string outputStr = generateFriendString(inputStr); cout << outputStr << endl; return 0; } 1. 引入库和命名空间 #include <iostream> #include <string> using namespace std;#include <iostream>: 引入输入输出流库,用于处理输入和输出。
#include <string>: 引入字符串库,以便使用 string 类型。
using namespace std;: 允许直接使用 std 命名空间中的元素,避免在使用标准库函数时加上 std:: 前缀。
2. 定义生成 Friend String 的函数 string generateFriendString(const string& s) {generateFriendString 函数接受一个常量字符串引用 s,返回一个字符串。
3. 初始化变量 string result; int n = s.length();创建一个空字符串 result 来存储生成的字符串。
获取字符串 s 的长度 n。
4. 遍历字符串 for (int i = 0; i < n; ++i) {使用 for 循环遍历字符串的每个字符。
5. 生成新字符 char newChar; if (i < n - 1) { newChar = s[i] + s[i + 1]; } else { newChar = s[i] + s[0]; }创建字符变量 newChar。
如果当前字符不是最后一个字符(i < n - 1),则将当前字符 s[i] 和下一个字符 s[i + 1] 相加,形成新的字符。
如果是最后一个字符(i == n - 1),则将该字符 s[i] 和第一个字符 s[0] 相加。
6. 添加新字符到结果字符串 result += newChar;将生成的新字符 newChar 添加到结果字符串 result 中。
7. 返回结果 return result;返回生成的字符串。
8. 主函数 int main() { string inputStr; cin >> inputStr; string outputStr = generateFriendString(inputStr); cout << outputStr << endl; return 0; }主函数中读取输入字符串 inputStr。
调用 generateFriendString 函数生成新字符串,并将结果存储在 outputStr 中。
输出生成的字符串。
注意需要注意的是,newChar = s[i] + s[i + 1]; 这一行实际上是将两个字符的 ASCII 值相加,结果会超出字符范围并无法直接表示为字符。这将导致 newChar 并不是一个有效的字符,可能会引发未定义行为。
代码改进建议如果想要将两个字符相加并保持在字符范围内,可以考虑将结果取模(例如,使用 % 256),或者根据需求定义如何处理字符的组合。例如:
newChar = (s[i] + s[i + 1]) % 256; // 保持在有效字符范围内或者,可以考虑使用字符串拼接,而不是将字符相加。具体实现取决于所需的逻辑和输出格式。
总结这段代码时间复杂度为O(n),展示了如何基于输入字符串生成一个新字符串的基本思路,但在字符相加的部分需要谨慎处理,以确保生成的字符在有效范围内。
评测记录: 五、B2114 配对碱基链 - 洛谷 方法一:算法代码(使用map一一对应) #include<bits/stdc++.h> using namespace std; char a[1000];//char型数组存字符串 int lena; map <char,char>ch;//map一一对应 int main() { cin>>a; lena=strlen(a);//strlen函数返回数组长度 ch['A']='T'; ch['T']='A'; ch['C']='G'; ch['G']='C';//一一对应 for(int i=0;i<lena;i++) cout<<ch[a[i]];//输出 return 0; } 1. 引入库 #include <bits/stdc++.h> using namespace std;#include <bits/stdc++.h>: 这个头文件包含了几乎所有的标准库,通常在竞争性编程中使用以节省输入时间。
2. 定义全局变量 char a[1000]; // char型数组存储字符串 int lena; map <char,char> ch; // map用于存储碱基一一对应关系char a[1000];: 定义一个字符数组 a,用于存储输入的 DNA 字符串,最大长度为 999 个字符(最后一个字符为字符串结束符 \0)。
int lena;: 定义一个整数变量 lena,用于存储字符串的长度。
map <char,char> ch;: 定义一个字符映射 ch,用于存储 DNA 碱基的互补关系。
3. 主函数 int main() {程序的主入口。
4. 读取输入 cin >> a; lena = strlen(a); // 用 strlen 函数返回数组长度从标准输入读取一个 DNA 字符串并存储到数组 a 中。
使用 strlen(a) 函数获取字符串的长度,并存储在 lena 中。
5. 定义碱基配对关系 ch['A'] = 'T'; ch['T'] = 'A'; ch['C'] = 'G'; ch['G'] = 'C'; // 定义碱基的互补关系使用 map 来定义碱基之间的互补关系:
‘A’ 与 ‘T’ 互补
‘T’ 与 ‘A’ 互补
‘C’ 与 ‘G’ 互补
‘G’ 与 ‘C’ 互补
6. 输出互补序列 for (int i = 0; i < lena; i++) cout << ch[a[i]]; // 输出互补序列使用 for 循环遍历输入字符串的每个字符,并通过 map ch 输出互补碱基。
7. 返回值 return 0;返回 0,表示程序正常退出。
总结这段代码实现了一个简单的 DNA 互补序列生成器。它通过读取一个 DNA 序列并利用 map 存储碱基之间的互补关系,然后输出对应的互补序列。代码结构清晰,能够有效处理 DNA 碱基互补逻辑,时间复杂度为 O(n),其中 n 是输入 DNA 序列的长度。
方法二:算法代码(直接替换) #include <bits/stdc++.h> using namespace std; char s[10001]; int main(){ cin>>s; for (int i=0;i<strlen(s);i++) if (s[i]=='A') cout<<"T"; else if (s[i]=='G') cout<<"C"; else if (s[i]=='T') cout<<"A"; else if (s[i]=='C') cout<<"G"; return 0; } 1. 引入库 #include <bits/stdc++.h> using namespace std;#include <bits/stdc++.h>: 这是一个包含了大多数标准库的头文件,通常用于竞争性编程以减少代码的输入量。
2. 定义字符数组 char s[10001];char s[10001];: 定义一个字符数组 s,用于存储输入的 DNA 字符串,最大长度为 10000 个字符(最后一个字符为字符串结束符 \0)。
3. 主函数 int main() {程序的主入口。
4. 读取输入 cin >> s;从标准输入读取一个 DNA 字符串并将其存储在数组 s 中。
5. 遍历字符串并转换碱基 for (int i = 0; i < strlen(s); i++) { if (s[i] == 'A') cout << "T"; else if (s[i] == 'G') cout << "C"; else if (s[i] == 'T') cout << "A"; else if (s[i] == 'C') cout << "G"; }使用 for 循环遍历字符串 s 的每个字符:
如果当前字符是 'A’,则输出 'T’(A 的互补碱基)。
如果当前字符是 'G’,则输出 'C’(G 的互补碱基)。
如果当前字符是 'T’,则输出 'A’(T 的互补碱基)。
如果当前字符是 'C’,则输出 'G’(C 的互补碱基)。
6. 返回值 return 0;返回 0,表示程序正常退出。
总结这段代码实现了一个简单的 DNA 互补序列生成器。通过读取一个 DNA 序列并根据碱基的配对规则输出对应的互补碱基,它的时间复杂度为 O(n),其中 n 是输入 DNA 序列的长度。
改进建议尽管这段代码功能正常,但有几个改进点可以考虑:
使用 strlen 的优化:每次调用 strlen(s) 会遍历整个字符串,导致效率下降。可以在循环开始前缓存字符串的长度:
int len = strlen(s); for (int i = 0; i < len; i++) { ... }使用 switch 语句:使用 switch 语句可以使代码更简洁、易读:
switch (s[i]) { case 'A': cout << "T"; break; case 'G': cout << "C"; break; case 'T': cout << "A"; break; case 'C': cout << "G"; break; }输入限制:可以加上对输入字符串的有效性检查,确保只有合法的 DNA 碱基被处理。
输出格式:在某些情况下,可能需要换行或分隔符来格式化输出。
以下是改进后的代码示例:
#include <bits/stdc++.h> using namespace std; char s[10001]; int main() { cin >> s; int len = strlen(s); // 缓存字符串长度 for (int i = 0; i < len; i++) { switch (s[i]) { case 'A': cout << "T"; break; case 'G': cout << "C"; break; case 'T': cout << "A"; break; case 'C': cout << "G"; break; } } return 0; }通过这些改进,代码会更加高效和清晰。
测评记录: 六、 B2116 加密的病历单 - 洛谷 算法代码: #include <iostream> #include <string> #include <algorithm> using namespace std; string decryptString(const string& s) { string result = s; // 1. 大小写反转 for (char& c : result) { if (isupper(c)) { c = tolower(c); } else if (islower(c)) { c = toupper(c); } } // 2. 逆序存储 reverse(result.begin(), result.end()); // 3. 字符循环右移三个位置 for (char& c : result) { if (isalpha(c)) { if (isupper(c)) { c = 'A' + (c - 'A' + 3) % 26; } else { c = 'a' + (c - 'a' + 3) % 26; } } } return result; } int main() { string inputStr; cin >> inputStr; string outputStr = decryptString(inputStr); cout << outputStr << endl; return 0; } 1. 引入库 #include <iostream> #include <string> #include <algorithm> using namespace std;#include <iostream>: 引入输入输出流库,用于处理输入和输出。
#include <string>: 引入字符串库,以便使用 string 类型。
#include <algorithm>: 引入算法库,以便使用标准算法,例如 reverse。
2. 定义解密函数 string decryptString(const string& s) {decryptString 函数接受一个常量字符串引用 s,返回一个解密后的字符串。
3. 初始化结果字符串 string result = s;创建一个新的字符串 result,并将输入字符串 s 复制到 result 中。
4. 步骤 1:大小写反转 for (char& c : result) { if (isupper(c)) { c = tolower(c); } else if (islower(c)) { c = toupper(c); } }使用范围 for 循环遍历 result 中的每个字符 c:
如果 c 是大写字母,则将其转换为小写字母。
如果 c 是小写字母,则将其转换为大写字母。
5. 步骤 2:逆序存储 reverse(result.begin(), result.end());使用 reverse 函数将 result 字符串中的字符顺序反转。
6. 步骤 3:字符循环右移三个位置 for (char& c : result) { if (isalpha(c)) { if (isupper(c)) { c = 'A' + (c - 'A' + 3) % 26; } else { c = 'a' + (c - 'a' + 3) % 26; } } }再次使用范围 for 循环遍历 result 中的每个字符 c:
检查字符是否为字母(isalpha(c))。
如果是大写字母,计算循环右移后的新字符:
使用 c - 'A' 将字母转换为 0 到 25 的范围,加上 3 后再取模 26,最后通过 'A' + 将其转换回字符。
如果是小写字母,执行相同的操作,但使用 'a' 为基准。
为什么使用模运算(% 26)字母表有 26 个字母(A-Z 或 a-z),因此字符的偏移量必须在 0 到 25 之间。
当字符的偏移量增加 3 后,可能会超出 25(例如,'x' 的偏移量是 23,增加 3 后变为 26)。
使用模运算 % 26 可以确保偏移量循环回到字母表的开头:
例如,26 % 26 = 0,对应字母 'a' 或 'A'。
这样,字符的移动是循环的,不会超出字母表的范围。
7. 返回结果 return result;返回解密后的字符串。
8. 主函数 int main() { string inputStr; cin >> inputStr; string outputStr = decryptString(inputStr); cout << outputStr << endl; return 0; }主函数中读取输入字符串 inputStr。
调用 decryptString 函数生成解密后的字符串,并将结果存储在 outputStr 中。
输出解密后的字符串。
总结这段代码有效地实现了一种字符串解密的方式。通过对输入字符串进行大小写反转、逆序和字符循环右移三个步骤,生成了新的字符串。时间复杂度为 O(n),其中 n 是输入字符串的长度。
评测记录: 七、B2117 整理药名 - 洛谷 算法代码: #include<bits/stdc++.h> using namespace std; int n,lena; char a[30];//char型数组存字符串 int main() { cin>>n; for(int i=0;i<n;i++) { cin>>a; lena=strlen(a);;//strlen返回char型数组的长度 if(islower(a[0])) a[0]-=32; //判断开头字符是否是小写字母,若是,则转化为大写 for(int j=1;j<lena;j++) if(isupper(a[j])) a[j]+=32; //判断其他字符是否为大写字母,若是,则转化为小写 cout<<a<<endl; } return 0; } 1. 引入必要的库 #include <iostream> #include <string> #include <algorithm> using namespace std;引入 <iostream> 进行输入输出操作。
引入 <string> 以使用 C++ 的 string 类型。
引入 <algorithm> 以使用一些算法函数,比如 toupper 和 tolower。
2. 定义主函数 int main() {定义程序的主入口。
3. 读取字符串数量 int n; cin >> n; cin.ignore(); // 忽略换行符声明一个整数 n 用于存储将要处理的字符串数量。
使用 cin >> n; 读取数量。
使用 cin.ignore(); 忽略后续的换行符,以便正确读取字符串。
4. 循环处理每个字符串 for (int i = 0; i < n; i++) { string a; getline(cin, a); // 使用 getline 读取字符串使用 for 循环遍历每个字符串。
声明一个 string 类型的变量 a 来存储当前字符串。
使用 getline(cin, a); 读取整行输入的字符串。
5. 格式化首字母为大写 if (islower(a[0])) { a[0] = toupper(a[0]); // 将首字母转为大写 }检查字符串的第一个字符是否为小写字母(islower)。
如果是,则使用 toupper 将其转换为大写。
6. 格式化其他字符为小写 for (int j = 1; j < a.length(); j++) { a[j] = tolower(a[j]); // 将剩余字符转为小写 }使用 for 循环遍历从第二个字符开始的每个字符。
使用 tolower 将每个大写字母转换为小写。
7. 输出格式化后的字符串 cout << a << endl; // 输出结果输出格式化后的字符串 a。
8. 结束主函数 return 0; }使用 return 0; 表示程序正常结束。
完整代码示例 #include <iostream> #include <string> #include <algorithm> using namespace std; int main() { int n; cin >> n; cin.ignore(); // 忽略换行符 for (int i = 0; i < n; i++) { string a; getline(cin, a); // 使用 getline 读取字符串 // 将首字母转为大写 if (islower(a[0])) { a[0] = toupper(a[0]); } // 将剩余字符转为小写 for (int j = 1; j < a.length(); j++) { a[j] = tolower(a[j]); } cout << a << endl; // 输出结果 } return 0; } 总结程序的时间复杂度是 ( O(n \cdot L) ),其中 ( n ) 是字符串的数量,( L ) 是每个字符串的平均长度。
评测记录: 八、B2118 验证子串 - 洛谷 算法代码: #include<bits/stdc++.h> using namespace std; string a,b; int main() { cin>>a>>b; if(a.find(b)!=a.npos) //如果b是a的子串 { cout<<b<<" is substring of "<<a<<endl; } else if(b.find(a)!=b.npos) //如果a是b的子串 { cout<<a<<" is substring of "<<b<<endl; } else //如果没有子串关系 { cout<<"No substring"<<endl; } return 0; } 1、代码思路:输入两个字符串:从标准输入读取两个字符串 a 和 b。
判断子串关系:
使用 a.find(b) 检查 b 是否是 a 的子串。
如果 b 是 a 的子串,输出 b is substring of a。
否则,使用 b.find(a) 检查 a 是否是 b 的子串。
如果 a 是 b 的子串,输出 a is substring of b。
如果两者都不是对方的子串,输出 No substring。
结束程序:返回 0,表示程序正常结束。
2、代码解释:a.find(b):在字符串 a 中查找子串 b。如果找到,返回子串的起始位置;否则返回 string::npos。
b.find(a):在字符串 b 中查找子串 a。如果找到,返回子串的起始位置;否则返回 string::npos。
if-else 结构:根据查找结果判断子串关系,并输出相应的信息。
3、代码优化建议:输入处理:确保输入的两个字符串不为空,避免不必要的错误。
大小写敏感:如果希望忽略大小写,可以在查找前将字符串统一转换为小写或大写。
边界情况:考虑空字符串的情况,避免程序崩溃。
4、优化后的代码: #include<bits/stdc++.h> using namespace std; int main() { string a, b; cin >> a >> b; if (a.empty() || b.empty()) { cout << "No substring" << endl; return 0; } if (a.find(b) != string::npos) { cout << b << " is substring of " << a << endl; } else if (b.find(a) != string::npos) { cout << a << " is substring of " << b << endl; } else { cout << "No substring" << endl; } return 0; } 5、优化点解释:空字符串检查:在查找子串之前,检查 a 和 b 是否为空字符串。如果为空,直接输出 No substring。
代码简洁性:保持代码逻辑清晰,易于理解。
评测记录 九、B2119 删除单词后缀 - 洛谷 算法代码: #include <iostream> #include <string> using namespace std; string removeSuffix(const string& word) { if (word.length() >= 2 && word.substr(word.length() - 2) == "er") { return word.substr(0, word.length() - 2); } if (word.length() >= 2 && word.substr(word.length() - 2) == "ly") { return word.substr(0, word.length() - 2); } if (word.length() >= 3 && word.substr(word.length() - 3) == "ing") { return word.substr(0, word.length() - 3); } return word; } int main() { string word; cin >> word; cout << removeSuffix(word) << endl; return 0; } 1、代码思路:输入处理:
从标准输入读取一个单词。
确保单词的长度不超过题目要求的最大长度(32个字符)。
后缀检查与删除:
检查单词是否以 er 结尾。如果是,删除最后两个字符。
检查单词是否以 ly 结尾。如果是,删除最后两个字符。
检查单词是否以 ing 结尾。如果是,删除最后三个字符。
如果单词不以任何指定的后缀结尾,则保持不变。
输出结果:
输出处理后的单词。
2、具体实现步骤:读取输入:
使用 cin 读取输入的单词。
后缀检查:
使用 substr 方法检查单词的最后几个字符是否与目标后缀匹配。
如果匹配,使用 substr 方法删除后缀。
输出结果:
使用 cout 输出处理后的单词。
评测记录: 十、 B2120 单词的长度 - 洛谷 算法代码: #include <bits/stdc++.h> using namespace std; int main() { string s; bool flag = true; while (cin >> s) { if (flag) { flag = false; cout << s.size(); } else { cout << ',' << s.size(); } } return 0; } 引入库 #include <bits/stdc++.h>引入标准库,提供各种数据结构和算法的支持。
定义主函数 int main() {程序的主入口。
声明变量 string s; bool flag = true;声明一个字符串变量 s 用于存储输入的每个单词。
声明一个布尔变量 flag,初始值为 true,用于控制输出格式。
循环读取输入 while (cin >> s) {使用 while 循环从标准输入中读取字符串 s,直到输入结束。
处理第一次输入 if (flag) { flag = false; cout << s.size(); }在第一次读取字符串时(即 flag 为 true),输出字符串 s 的长度,并将 flag 设置为 false,以便后续输入的处理。
处理后续输入 else { cout << ',' << s.size(); }对于后续读取的字符串,输出一个逗号 ,,然后输出字符串 s 的长度。
结束主函数 return 0; }返回 0,表示程序正常结束。
总结该程序的功能是从标准输入中逐个读取字符串,并输出每个字符串的长度。对于第一个字符串,它直接输出长度;对于后续的字符串,它在长度前添加一个逗号分隔符。最终输出的是所有输入字符串长度的逗号分隔列表。综上所述,循环体内的操作(读取字符串、计算长度和输出长度)都是 ( O(1) ) 的,因此整个程序的时间复杂度为: [ O(n) ] 其中 ( n ) 是输入中字符串的数量。也就是说,程序的运行时间是线性于输入字符串数量的。
评测记录:STL——洛谷字符串(string库)入门题(蓝桥杯题目训练)(一)由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“STL——洛谷字符串(string库)入门题(蓝桥杯题目训练)(一)”