深入浅出程序设计竞赛(基础篇)-第六章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。

  1. strlen函数来查询字符串的长度。
  2. strcpy可用来复制字符数组
  3. 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函数可以读取一行文本,包括空格
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐