23级深技大OJ平台C语言实验课实验十一 ABCDE题

        6666666

        为什么感觉acm的佬们都更喜欢c++……平时发的很多题解都是c++写的……

        2023.12.3更新A题

        2023.12.4更新E题


【id:386】【20分】A. 实验6-2 英文字母替换加密(大小写转换+后移1位)

不清楚ascii码的可以看看以前写的内容   实验六的A题

#include <stdio.h>

int main() {
	char c;
	while (1) {
		scanf("%c", &c);
		if (c == '\n')
			break;

		if ('a' <= c && c <= 'y') {
			printf("%c", c + 1 + 'A' - 'a');
		} else if ('A' <= c && c <= 'Y') {
			printf("%c", c + 1 - ('A' - 'a'));
		} else if (c == 'z' || c == 'Z') {  //特判z和Z
			printf("%c", c == 'z' ? 'A' : 'a');  //如果c=='z',返回'A',否则返回'a'
		} else
			printf("%c", c);
	}

	return 0;
}

注意z和Z需要特判!!!不然一往后移就跑到别的奇怪符号了

暂时还没想到不需要特判的方法……(不知道链表可不可以…?还没学。。等学了就回来更新

——————————2023.12.3更新线————————————————————

!!!喜报喜报!!夫人生了!!!!特别点名czx笑脸哥提供的方法!!!!!!

#include <stdio.h>

int main() {
	char c;
	while (1) {
		scanf("%c", &c);
		if (c == '\n')
			break;

		if ('a' <= c && c <= 'z') {
			printf("%c", (c-'a'+1)%26 + 'A');  //(c-'a'+1)可替换为(c-96)
		} else if ('A' <= c && c <= 'Z') {
			printf("%c", (c-'A'+1)%26 + 'a'); //(c-'a'+1)可替换为(c-64)
		}else
			printf("%c", c);
	}

	return 0;
}

可以看下面的ascii码值表。将c减去一个'a'再加1就能得到c在字母表中的位次。如'a'-'a'+1=1

所以将位次计算出来后再%26就相当于特判了z和Z的情况(26%26+'A'='A')

 啊啊啊啊啊啊啊天才!!!!!

——————————————手动分割线——————————————

下面是不停叠三目运算的抽象版:(写的时候思路很清晰,但是写完真的就。。。理不清了)

#include <stdio.h>

int main() {
	char c;
	while (1) {
		scanf("%c", &c);
		if (c == '\n')
			break;
		c = 'a' <= c && c <= 'y' ? c + 1 + 'A' - 'a' : 'A' <= c && c <= 'Y' ? c + 1 - ('A' - 'a') : c == 'z'|| c == 'Z' ? c == 'z' ? 'A' : 'a' : c;
		printf("%c", c);
	}

	return 0;
}

【id:387】【20分】B. 实验6-1 近似求PI

复习时间到!!

%e:使用科学计数法的浮点数,指数部分的e为小写

%E:使用科学计数法的浮点数,指数部分的E为大写

%le:科学计数法表示的 long double 类型浮点数

#include <stdio.h>

int main() {
	double eps, x = 1, y = 1;
	scanf("%le", &eps);
	for (int i = 1, j = 3; x >= eps; i++, j += 2) {  //i用来分子乘,j用来分母除
		x = i * x / j;  //直接在前一项的基础上做运算
		y += x;
	}
	printf("PI = %.5lf", 2 * y);

	return 0;
}

【id:383】【20分】C. 实验6-5 简单计算器

思路:
1.不断读入单个字符
2.读入的如果为数字,则需要再一次读入字符时才能运算(注意有多位数)
3.读入的如果为运算符则保存,直到完整读入运算符后的数字才进行相应运算
4.注意特判/0情况
#include <stdio.h>

int main()
{
	char c, d = '+';  //默认第一个数字为加到y里
	int y = 0, tmp = 0;  //y记录总的运算结果,tmp记录读入的数字
	while (1)
	{
		scanf("%c", &c);
		if ('0' <= c && c <= '9')  //数字情况
			tmp = 10 * tmp + (int)c - 48;
		else //非数字情况
		{
			y = d == '+' ? y + tmp : d == '-' ? y - tmp : d == '*' ? y * tmp : d == '/' ? y / tmp : y; //运算符的处理
			if (tmp == 0 && d == '/') //特判除0的特殊情况
			{
				printf("ERROR");
				return 0;
			}
			if (c == '=')
				break;
			d = c, tmp = 0; //保存这次读入的运算符c,用于下一次运算;重置tmp为0
		}
	}
	printf("%d", y);

	return 0;
}

第11行用了强制转换类型。c的强制类型转换时括住要变成的类型,后面接要操作的对象。如(int)c;而python的强制转换类型则是括住要操作的对象,如int(c);

(int)c返回的结果是c字符对应的ascii码值。需要注意的是单个数字的ascii码值并不等于他本身。如'1'对应的ascii码值是49,'2'对应的ascii码值是50。因此11行才在后面又减去了48;

第14行因为不想写好多if else所以就叠了好多三目运算……可以试试能不能理清上面的三目运算。

暂时没想到怎么不用单独 if 拎出/0情况的方法。


【id:384】【20分】D. 实验6-4 单词首字母大写

梦回期中考howareyou题……这就是期中考那道题的降维版本

思路:
1.为了判断读入的字符是否是单词的首字母需要定义一个flag。如果遇到了空格则给flag赋值为0,代表下一个读入的字母需要大写,如果遇到了字母则给flag赋值为1,代表后面的字母都不需要大写。
2.判断循环结束的条件。(因为题目没说……那就按自己的理解判断,应该是读到非子母又非空格的字符就结束)
#include <stdio.h>

int main()
{
	char c;
	int flag = 0;  //flag用来判断是否需要大写 0:大写;1:小写
	while (1)
	{
		scanf("%c", &c);
		if ('A' <= c && c <= 'Z')  //若读入大写则先变为小写
			c -= 'A' - 'a';
			
		if ('a' <= c && c <= 'z')  //读入小写时
		{
			if (flag == 0)  //若为0则变为大写
				c += 'A' - 'a';
			flag = 1;
		}
		else if (c == ' ')  //当读入空格时
			flag = 0;
		else  //当读入其他字符时
		{
			printf("%c", c);
			break;
		}
		printf("%c", c);
	}

	return 0;
}

我写出来的代码看起来由宽到窄有点难看……

关于if else的执行规则:按顺序从上到下判断,只要谁的条件成立了,就只执行它,后面的其他情况一律跳过。因为读入是字母的情况明显是要多于空格或是其他字符的,所以第13到25行的if else这里就把判断字母放在了最上面,判断其他字符放在了最下面,这样可以少点运行时间(但是这道题循环次数的数量级不大所以其实无所谓……)

有兴趣的可以去了解一下时间复杂度(就算现在不学以后算法课也必须要学的)


【id:378】【20分】E. 实验6-10 统计单词的长度

思路:
1.判断单词的结束和起点,记录长度并printf出来
2.因为存在中间连续出现空格的情况,所以不能一遇到空格就无脑printf
3.因为存在全是空格的情况,所以在写的时候需要注意特判

 下面这个是我写的,但是再下面有个2023.12.4从评论区更新的更清晰的代码!!!!!那个真的超级好!!!!!

#include <stdio.h>

int main()
{
	char c;
	int flag = 0,flag2 = 0,y = 0;  //flag记录上一个读入字符是否是字母,是则1,否则0; flag2记录是否出现过字母; y记录单词长度
	while (1)
	{
		scanf("%c", &c);

		if ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c != ' ' && c != '\n')  //读入字母或非空格和换行字符时
		{
			flag = 1, flag2 = 1;
			y++;
		}
		else  //当读入空格或换行时
		{
			if (flag == 1)  //上一个读入的字符是字母或是符号时
				printf("%d ", y);
			flag = 0, y = 0;  //重置flag和y
			if (c == '\n')
			{
				if (flag2 == 0)  //特判全是空格情况
					printf("0 ");
				return 0;
			}
		}
	}

	return 0;
}

因为要记录是否出现过空格所以多定义了flag2。

或者其实也可以不多定义flag2,只使用flag也可以完成(不嫌更麻烦的话)。比如我们将flag定义为double型,如果出现字母则对他的小数部分做一些特殊的标记。不过这样子里面的各种if条件不仅要大改还要加很多东西。。。。

如果有更好的方法请一定要跟我讲讲啊啊啊啊啊!!!!!!!!!!!!!!!

——————————2023.12.4更新线!————————

评论区Banlangk给出了只用一个flag的代码!!

#include <stdio.h>
 
int main(void)
{
	char ch;
	int cnt = 0, flag = 1;
	while ((ch = getchar()) != '\n')
	{
		if (ch == ' ')
		{
			if (cnt != 0)
			{
				printf("%d ", cnt);
				cnt = 0;
			}
		}
		else
		{
			cnt++;
			flag = 0;
		}
	}

	// 特殊处理
	if (cnt != 0 || flag)
		printf("%d ", cnt);
 
	return 0;
}

下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训下周军训……

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值