STL —— 洛谷字符串(string库)入门题(蓝桥杯题目训练)(一)

目录

一、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 序列的长度。

改进建议

尽管这段代码功能正常,但有几个改进点可以考虑:

  1. 使用 strlen 的优化:每次调用 strlen(s) 会遍历整个字符串,导致效率下降。可以在循环开始前缓存字符串的长度:

    int len = strlen(s);
    for (int i = 0; i < len; i++) { ... }
    
  2. 使用 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;
    }
    
  3. 输入限制:可以加上对输入字符串的有效性检查,确保只有合法的 DNA 碱基被处理。

  4. 输出格式:在某些情况下,可能需要换行或分隔符来格式化输出。

以下是改进后的代码示例:

#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、代码思路:

  1. 输入两个字符串:从标准输入读取两个字符串 a 和 b

  2. 判断子串关系

    • 使用 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

  3. 结束程序:返回 0,表示程序正常结束。

2、代码解释:

  • a.find(b):在字符串 a 中查找子串 b。如果找到,返回子串的起始位置;否则返回 string::npos

  • b.find(a):在字符串 b 中查找子串 a。如果找到,返回子串的起始位置;否则返回 string::npos

  • if-else 结构:根据查找结果判断子串关系,并输出相应的信息。

3、代码优化建议:

  1. 输入处理:确保输入的两个字符串不为空,避免不必要的错误。

  2. 大小写敏感:如果希望忽略大小写,可以在查找前将字符串统一转换为小写或大写。

  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、优化点解释:

  1. 空字符串检查:在查找子串之前,检查 a 和 b 是否为空字符串。如果为空,直接输出 No substring

  2. 代码简洁性:保持代码逻辑清晰,易于理解。

评测记录

九、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、代码思路:

  1. 输入处理

    • 从标准输入读取一个单词。

    • 确保单词的长度不超过题目要求的最大长度(32个字符)。

  2. 后缀检查与删除

    • 检查单词是否以 er 结尾。如果是,删除最后两个字符。

    • 检查单词是否以 ly 结尾。如果是,删除最后两个字符。

    • 检查单词是否以 ing 结尾。如果是,删除最后三个字符。

    • 如果单词不以任何指定的后缀结尾,则保持不变。

  3. 输出结果

    • 输出处理后的单词。

2、具体实现步骤:

  1. 读取输入

    • 使用 cin 读取输入的单词。

  2. 后缀检查

    • 使用 substr 方法检查单词的最后几个字符是否与目标后缀匹配。

    • 如果匹配,使用 substr 方法删除后缀。

  3. 输出结果

    • 使用 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;
}
  1. 引入库

    #include <bits/stdc++.h>
    
    • 引入标准库,提供各种数据结构和算法的支持。

  2. 定义主函数

    int main() {
    
    • 程序的主入口。

  3. 声明变量

    string s;
    bool flag = true;
    
    • 声明一个字符串变量 s 用于存储输入的每个单词。

    • 声明一个布尔变量 flag,初始值为 true,用于控制输出格式。

  4. 循环读取输入

    while (cin >> s) {
    
    • 使用 while 循环从标准输入中读取字符串 s,直到输入结束。

  5. 处理第一次输入

    if (flag) {
        flag = false;
        cout << s.size();
    }
    
    • 在第一次读取字符串时(即 flag 为 true),输出字符串 s 的长度,并将 flag 设置为 false,以便后续输入的处理。

  6. 处理后续输入

    else {
        cout << ',' << s.size();
    }
    
    • 对于后续读取的字符串,输出一个逗号 ,,然后输出字符串 s 的长度。

  7. 结束主函数

    return 0;
    }
    
    • 返回 0,表示程序正常结束。

总结

        该程序的功能是从标准输入中逐个读取字符串,并输出每个字符串的长度。对于第一个字符串,它直接输出长度;对于后续的字符串,它在长度前添加一个逗号分隔符。最终输出的是所有输入字符串长度的逗号分隔列表。综上所述,循环体内的操作(读取字符串、计算长度和输出长度)都是 ( O(1) ) 的,因此整个程序的时间复杂度为: [ O(n) ] 其中 ( n ) 是输入中字符串的数量。也就是说,程序的运行时间是线性于输入字符串数量的。

评测记录:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/971972.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang GORM系列:GORM并发与连接池

GORM 是一个流行的 Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;用于简化数据库操作。它支持连接池和并发访问功能&#xff0c;这些功能对于高性能、高并发的应用场景非常重要。本文结合示例详细介绍gorm的并发处理能力&#xff0c;以及如何是哟个连接池提升…

C#之上位机开发---------C#通信库及WPF的简单实践

〇、上位机&#xff0c;分层架构 界面层 要实现的功能&#xff1a; 展示数据 获取数据 发送数据 数据层 要实现的功能&#xff1a; 转换数据 打包数据 存取数据 通信层 要实现的功能&#xff1a; 打开连接 关闭连接 读取数据 写入数据 实体类 作用&#xff1a; 封装数据…

Ubuntu24安装MongoDB(解压版)

目录 0.需求说明1.环境检查2.下载软件2.1.下载MongoDB服务端2.2.下载MongoDB连接工具(可略过)2.3.检查上传或下载的安装包 3.安装MongoDB3.1.编辑系统服务3.2.启动服务3.3.客户端连接验证3.3.1.创建管理员用户 4.远程访问4.1.开启远程访问4.2.开放防火墙 0.需求说明 问&#x…

《DeepSeek-V3:人工智能大语言模型》

《DeepSeek-V3:人工智能大语言模型》 1. 引言 我们介绍了 DeepSeek-V3,这是一个强大的专家混合 (MoE) 语言模型,总共有 671B 个参数,每个令牌激活了 37B。 为了实现高效的推理和具有成本效益的训练,DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些…

解锁机器学习核心算法 | K -近邻算法:机器学习的神奇钥匙

一、引言 今天我们继续学习机器学习核心算法 —— K - 近邻&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;算法。它就像是一位经验丰富的 “老江湖”&#xff0c;以其简单而又强大的方式&#xff0c;在众多机器学习任务中占据着不可或缺的地位。 K - 近邻…

算法分析—— 《归并排序》

《排序数组》 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题&#xff0c;时间复杂度为 O(nlog(n))&#xff0c;并且空间复杂度尽可能小。 示例 1&#xff1a; 输入&#xff1a;nums [5,2…

linux云服务器部署deepseek,并通过网页访问

参考视频&#xff1a;https://www.douyin.com/root/search/linux%E5%AE%89%E8%A3%85%20deepseek?aid3aa2527c-e4f2-4059-b724-ab81a140fa8b&modal_id7468518885570940214&typegeneral 修改ollama配置文件 vim /etc/systemd/system/ollama.service 我的电脑硬盘只有4…

FastAdmin后端列表导入表格数据

后台添加数据的时候增加通过表格导入功能 如下图index.html页面增加导入和模板下载按钮代码如下 <div class"panel panel-default panel-intro">{:build_heading()}<div class"panel-body"><div id"myTabContent" class"ta…

可调节图片参数,解决图片模糊及尺寸过小问题的工具

软件介绍 你是否正为图片模糊、尺寸太小而烦恼&#xff1f;别担心&#xff0c;有这样一款神器能帮你轻松解决。它能精准调节图片参数&#xff0c;即便原本模糊不清的图片&#xff0c;经它处理后也能变得高清锐利&#xff0c;瞬间让图片焕然一新。而且&#xff0c;它还具备导出…

Windows网络安全基础

随着互联网的发展和普及&#xff0c;Windows网络安全问题愈发严重。在本文中&#xff0c;我们将会介绍Windows网络安全的基本概念&#xff0c;包括网络攻击类型、网络安全威胁、网络安全防御措施等等&#xff0c;帮助初学者更好地了解Windows网络安全。 一、网络攻击类型 网络…

代码补全『三重奏』:EverEdit如何用上下文识别+语法感知+智能片段重构你的编码效率!

1 代码自动完成 1.1 应用场景 在编辑文档时&#xff0c;为了提高编辑效率&#xff0c;编辑器一般都会带有自动完成功能&#xff0c;比如&#xff1a;输入括号时自动补全另一半&#xff0c;输入文字时&#xff0c;自动补全剩下的部分。 1.2 使用方法 1.2.1 自动缩进 单击主菜…

vue,vue3 keepalive没有效果,无法缓存页面include无效,keep-alive

keepalive没有效果&#xff0c;无法缓存页面&#xff1f; 问题大概是组件的name值不对应&#xff0c;vue2修改组件文件的name值&#xff0c;vue3保持组件文件名称和路由页面配置的name一致就可以了&#xff0c;如果vue3不想保持一致&#xff0c;必须手动在文件后面添加export..…

栈回溯方案

注&#xff1a;栈回溯无法很好的定位到未调优化的函数&#xff0c;需要编译前使用 -fno-optimize-sibling-calls 选项禁止尾调优化。 基于unwind的栈回溯 在 arm 架构下&#xff0c;不少32位系统用的是 unwind 形式的栈回溯&#xff0c;这种栈回溯要复杂很多。首先需要程序有一…

【存储中间件API】MySQL、Redis、MongoDB、ES常见api操作及性能比较

常见中间件api操作及性能比较 ☝️ MySQL crud操作✌️ maven依赖✌️ 配置✌️ 定义实体类✌️ 常用api ☝️ Redis crud操作✌️ maven依赖✌️ 配置✌️ 常用api ☝️ MongoDB crud操作✌️ maven依赖✌️ 配置文件✌️ 定义实体类✌️ MongoDB常用api ☝️ ES crud操作 ⭐️…

解锁D3.js与PlantUML的交互奥秘:探索知识图谱数据可视化新领域

解锁D3.js与PlantUML的交互魔法&#xff1a;数据可视化新征程 在前端开发的广袤天地里&#xff0c;数据可视化一直是一颗璀璨的明珠&#xff0c;吸引着无数开发者探索其奥秘。而当D3.js这一强大的JavaScript库&#xff0c;遇上专注于创建UML图的PlantUML&#xff0c;一场奇妙的…

DeepSeek24小时写作机器人,持续创作高质量文案

内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求&#xff0c;人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容&#xff1f;DeepSeek写作机器人&#xff0c;一款24小时持续创作的智能工具&#xff0c;为企业和个人提…

使用html css js 来实现一个服装行业的企业站源码-静态网站模板

最近在练习 前端基础&#xff0c;html css 和js 为了加强 代码的 熟悉程序&#xff0c;就使用 前端 写了一个个服装行业的企业站。把使用的技术 和 页面效果分享给大家。 应用场景 该制衣服装工厂官网前端静态网站模板主要用于前端练习和编程练习&#xff0c;适合初学者进行 HT…

使用html css js 开发一个 教育机构前端静态网站模板

这个教育机构网站模板是专为前端开发初学者设计的练习项目&#xff0c;适合正在学习前端的学生或自学者使用。网站内容包括首页、课程体系、师资力量、关于我们和联系我们等基础页面&#xff0c;帮助学习者熟悉网页布局、样式设计和交互功能的实现。 静态页面 简单截图 应用…

(蓝桥杯——10. 小郑做志愿者)洛斯里克城志愿者问题详解

题目背景 小郑是一名大学生,她决定通过做志愿者来增加自己的综合分。她的任务是帮助游客解决交通困难的问题。洛斯里克城是一个六朝古都,拥有 N 个区域和古老的地铁系统。地铁线路覆盖了树形结构上的某些路径,游客会询问两个区域是否可以通过某条地铁线路直达,以及有多少条…

React 低代码项目:网络请求与问卷基础实现

&#x1f35e;吐司问卷&#xff1a;网络请求与问卷基础实现 Date: February 10, 2025 Log 技术要点&#xff1a; HTTP协议XMLHttpRequest、fetch、axiosmock.js、postmanWebpack devServer 代理、craco.js 扩展 webpackRestful API 开发要点&#xff1a; 搭建 mock 服务 …