深入浅出程序设计竞赛(基础篇)-第六章C++代码及笔记
本文介绍了C++中字符串处理的基础知识,包含五个编程实例:1) 字符大小写转换的两种实现方法;2) 凯撒密码的字符偏移处理;3) 统计字母出现频率并判断质数差;4) 多行算式处理的输入输出技巧;5) 字符串长度统计。示例代码演示了字符数组操作、getchar/putchar使用、strlen/strcpy/strcmp等字符串函数,以及fgets/sscanf/sprintf等高级输入输出方法。文
深入浅出程序设计竞赛(基础篇)-第六章C++代码及笔记
6-1 字符修正
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
//写法一:
char s[110];
scanf("%s", s);
for (int i = 0; s[i] != '\0'; i++)
if ('a' <= s[i] && s[i] <= 'z') //C++可以直接比较字符的大小
s[i] = s[i] - 'a' + 'A'; //将小写字母转换为大写字母(写法1)
printf("%s\n", s);
return 0;
}
- getchar(); //输入一个字符
- putchar(); //输出一个字符
- gets(): //输入一个字符串,并将其存储在指定的字符数组中,直到遇到换行符为止(不再使用)
- puts(); //输出一个字符串,并在末尾添加一个换行符
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
//写法二:
char s;
while (1) {
s = getchar(); //每次调用getchar()函数都会从输入流中读取一个字符,并将其存储在变量s中
if (s == EOF) break; //当输入结束时,getchar()函数会返回EOF(End Of File),表示没有更多的字符可供读取
if ('a' <= s && s <= 'z') //如果s是小写字母
s = s + 'A' - 'a'; //将小写字母转换为大写字母(写法2)
putchar(s); //输出一个字符
}
}
6-2
凯撒密码是由原文字符串(由不超过50个小写字母组成)中每个字母向后移动位形成的。z的下一个字母是a,如此循环。给出和移动前的原文字符串,请求出密码。
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
int n;
char s[60];
scanf("%d %s", &n, &s);
for (int i = 0; s[i]; i++) {
putchar((s[i] - 'a' + n) % 26 + 'a'); //计算偏移量并还原
}
return 0;
}
6-3 统计字符串中字母出现次数
给出一个单词(由不超过100个小写字母组成)假设maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个LauckyWord,输出LuckyWord,然后在第二行输出maxn-minn的值:否则输出NoAnswer,第二行输出0。
- strlen函数来查询字符串的长度。
- strcpy可用来复制字符数组
- strcmp可用于比较两个字符数组(按照字典序)。
字符数组如何赋值一个字符串常量呢?不能直接赋值,因为字符数组的数组名也只是一个
数组名:使用strcpy()函数来复制一遍字符串常量到字符数组中,例如chara[100]; strcpy(a,“hello”);。
类似的,将字符数组b的字符串中的内容赋值到字符数组a,也是不能直接赋值的,必须用strcpy(a,b)。
但是在初始化的时候例外:在初始化的时候可以像初始化数组那样赋值一个字符串常量,例如char a[100]=“Luogu!”
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
char a[110];
int ans[26] = { 0 }; //ans[0]-ans[25]分别存储a-z的出现次数
int l, maxn, minn, delta; //l是字符串长度,maxn是出现次数最多的字母的次数,minn是出现次数最少的字母的次数,delta是maxn和minn的差值
scanf("%s", a);
//strlen()函数可以计算字符串的长度,返回值是字符串中字符的个数,不包括字符串末尾的'\0'字符。
l = strlen(a);
for (int i = 0; i < l; i++) ans[a[i] - 'a']++; //统计每个字母出现的次数,a[i]-'a'将字符转换为对应的索引,例如'a'对应0,'b'对应1,以此类推
maxn = 0; //最大值初始化
minn = 10000; //最小值初始化
for (int j = 0; j < 26; j++) {
if (ans[j] > maxn) maxn = ans[j]; //如果超过最大值
if (ans[j] != 0 && ans[j] < minn) minn = ans[j]; //如果不为0且小于最小值
}
delta = maxn - minn; //计算差值
if (delta == 0 || delta == 1) { //质数特别判断
printf("No Answer\n0");
return 0;
}
for (int h = 2; h * h <= delta; h++) { //枚举质数
if (delta % h == 0) {
printf("No Answer\n0");
return 0;
}
}
printf("Lucky Word\n%d\n", maxn - minn);
return 0;
}
6-4 多行读入与多行输出
王老师收集了:(i<50)道学生经常做错的口算题,并且想整理编写成一份练习。王老师希望尽量减少输人的工作量,比如5+8的算式最好只输人5和8,输出的结果要尽量详细以方便后期排版使用。对于上述输人进行处理后,输出5+8=13以及该算式的总长度6。输人数据第1行是i,接着的:行是需要输人的算式,每行可能有3个数据或两个数据。
1)若该行是3个数据,则第一个数据表示运算类型,a表示加法运算,b表示减法运算,表示乘法运算,接着的两个数据表示参加运算的运算数。
2)若该行是两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数。
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
int n, a, b, c;
char last, s[20], ans[20];
scanf("%d\n", &n);
while (n--) {
fgets(s, sizeof(s), stdin); // 读取整行输入
if (s[0] == 'a' || s[0] == 'b' || s[0] == 'c') {
last = s[0];
s[0] = ' '; //获取计算符号,并替代为空格
}
sscanf(s, "%d %d", &a, &b);
switch (last) {
case 'a': c = a + b; sprintf(ans, "%d+%d=%d", a, b, c); break; //+
case 'b': c = a - b; sprintf(ans, "%d-%d=%d", a, b, c); break; //-
case 'c': c = a * b; sprintf(ans, "%d*%d=%d", a, b, c); break; //*
}
printf("%s\n%d\n", ans, strlen(ans));
}
//return 0;
}
- fgets函数可以读取整行输入,包括空格,直到遇到换行符或文件结束符为止。它的参数包括一个字符数组、数组的大小和输入流。
- stdin是标准输入流,通常指键盘输入。使用fgets函数可以避免scanf在读取字符串时遇到空格而导致的问题。
- sscanf函数用于从字符串中读取格式化数据。它的参数包括一个字符串、一个格式字符串和要存储数据的变量地址。
- sprintf函数用于将格式化数据写入字符串。它的参数包括一个字符数组、一个格式字符串和要写入的数据。
- strlen函数用于计算字符串的长度,不包括字符串末尾的空字符。
6-5 string字符串类型
凯凯刚写了一篇美妙的作文,请统计这篇作文的标题中有多少个字符。注意:标题中可能包含大、小写英文字母、数字字符、空格和换行符,且字符串中的字符和空格数总和不超过5。统计标题字符数时,空格和换行符不计算在内。
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
string s;
int ans = 0;
/*输人时使用cin语句,不断读入字符串。当发现读入文件读完后(遇到EOF,在标准输入的
时候可以按Ctrl + Z组合键),cin >> s本身就会返回0,中断while语句,结束读入*/
while (cin >> s) ans += s.length();
cout << ans << endl;
return 0;
}
- string是一种数据类型,用来存储一个字符串。
- .length()是string类的一个成员函数,用来返回字符串的长度。
6-6 后插、截断、插入、查找函数
现在需要开发一款文字处理软件。最开始时输入一个字符串(不超过100个字符)作为初始文档。
可以认为文档开头是第0个字符,需要支持以下操作。
1)1 str:后接插入,在文档后面插入字符串str,并输出文档的字符串。
2)2 a b:截取文档部分,只保留文档中从第:个字符起b个字符,并输出文档的字符串。
3)3 a str:插入片段,在文档中第a个字符前面插入字符串str,并输出文档的字符串。
4)4 str:查找子串,查找字符串str在文档中最先出现的位置并输出;如果找不到输出-1。
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
int n, opt, l, r;
string s, a;
cin >> n;
cin >> s;
while (n--) {
cin >> opt;
if (opt == 1) {
cin >> a;
//使用append函数在字符串s后面添加字符串a
s.append(a);
cout << s << endl;
}
else if (opt == 2) {
cin >> l >> r;
//使用substr函数截取字符串s中从第l个字符开始的r个字符
s = s.substr(l, r);
cout << s << endl;
}
else if (opt == 3) {
cin >> l >> a;
//使用insert函数在字符串s中第l个字符前面插入字符串a
s.insert(l, a);
cout << s << endl;
}
else {
cin >> a;
//使用find函数查找字符串a在字符串s中最先出现的位置
cout << (int)s.find(a) << endl;
}
}
return 0;
}
- 使用append函数在字符串s后面添加字符串a;
- 使用substr函数截取字符串s中从第l个字符开始的r个字符;
- 使用insert函数在字符串s中第l个字符前面插入字符串a;
- 使用find函数查找字符串a在字符串s中最先出现的位置。
6-7
给定一个单词(长度不超过10,仅由英文字母组成)请输出它在给定的文章(长度不超过1000000,包括字母和空格)中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配所有字母。
#define _CRT_SECURE_NO_WARNINGS //不使用scanf_s
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define MAXN 1024
#define INF 1e9
#define PI 3.141593
//#define maxn 520
using namespace std;
int main()
{
string word, s;
getline(cin, word);
getline(cin, s);
for (int i = 0; i < word.length(); i++) {
if ('A' <= word[i] && word[i] <= 'Z') {
word[i] = word[i] - 'A' + 'a'; //将给定单词的所有大写字母转换为小写字母
}
for (int i = 0; i < s.length(); i++) {
if ('A' <= s[i] && s[i] <= 'Z') {
s[i] = s[i] - 'A' + 'a'; //将文章中的所有大写字母转换为小写字母
}
}
word = ' ' + word + ' '; //将给定单词前后都加上空格,防止多算
return 0;
}
- getline函数可以读取一行文本,包括空格
更多推荐



所有评论(0)