C语言PAT刷题 - 1009 说反话

这篇博客介绍了一种用C语言解决将英文句子中单词顺序反转的问题。作者首先讲解了题目的要求和解题思路,包括接收字符串、遍历并反转单词顺序,然后提供了两段代码实现,分别是基础版和优化版。基础版通过一维数组处理,优化版则使用了二维数组,更高效地处理单词存储和反转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者的话:若有朋友复制代码去PAT试着运行遇到问题的:
1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了;
2.可能是注释原因,PAT有时候检测到注释会编译错误,所以可以先把注释删了,再进行提交回答。
3.可能是作者当初根据题目写出来的代码仍存在一些疏漏,而恰好当时的测试机制没那么完善,没检测出问题。后面测试机制有所更新,故出现问题,若有相关需要的可以评论区留言或私信作者,我看到的话会去再查一下疏漏之处,然后更新文章。

一、题目描述
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello

二、解题思路
读题:

接收一串总长度不超过80的字符串(字符串为单词+空格+单词+…的形式),将单词的排列顺序颠倒输出。
思路:
1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),利用循环从键盘接收整个字符串存储在字符数组a中;
2.利用循环和判断语句从后往前遍历整个字符数组,以空格和换行符为判断条件,打印空格和空格之间、空格和换行符之间的一连串字符(因为是从后往前遍历,所以打印顺序是先打印最后一个单词,再打印前面一个单词,以此类推)。打印完一个单词后,再打印一个空格字符;
3.打印字符串的第一个单词(字符串的第一个单词由于并不被空格、字符串包围,所以思路2并不会打印第一个单词)。

三、具体实现
0.标准C源程序框架

#include <stdio.h>
int main()
{
    return 0;
}

1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),利用循环从键盘接收整个字符串存储在字符数组a中;

	char a[82];
	int i = 0;
	int j = 0;
	do
	{
		scanf("%c",&a[i++]);
	} while (a[i-1] != '\n');

2.利用循环和判断语句从后往前遍历整个字符数组,以空格和换行符为判断条件,打印空格和空格之间、空格和换行符之间的一连串字符(因为是从后往前遍历,所以打印顺序是先打印最后一个单词,再打印前面一个单词,以此类推)。打印完一个单词后,再打印一个空格字符;

	for (; i > 0; i--)
	{
		if (a[i - 1] == ' ')
		{
			j = i;
			while ((a[j]!=' ')&&(a[j]!='\n'))
			{
				printf("%c", a[j++]);
			}
			printf(" ");
		}
	}

3.打印字符串的第一个单词(字符串的第一个单词由于并不被空格、字符串包围,所以思路2并不会打印第一个单词)。

	while ((a[i] != ' ') && (a[i] != '\n'))
	{
		printf("%c", a[i++]);
	}

四、全部代码

#include <stdio.h>
int main()
{
	//目标:hello world\n -> world hello
	//我最先想到的是创建二维数组a[80][80],一行代表一个单词,可是数组内容学的不到家,弄了半天没弄好,只能回归一维数组
	char a[81];//后面接收字符串时,会存储输入的一连串字符加回车字符,所以考虑最坏的情况,数组必须能存储81个字符
	int i = 0;//循环变量,挺多地方用到的
	int j = 0;
	do
	{
		scanf("%c",&a[i++]);//一轮循环接收一个字符,直到接收到换行符,循环结束,此时i的值比接收了换行符的元素的下标大1
	} while (a[i-1] != '\n');
	for (; i > 0; i--)//从后往前遍历
	{
		if (a[i - 1] == ' ')//当当前元素的前面一个元素是空格时,执行分支
		{         //这个分支用来将空格和空格/换行符之间的一连串字符(单词)和空格打印出来
			j = i;//打印完一个单词后,i还要继续向前遍历,所以要保留i的值,但又要打印后面几位元素的值
			while ((a[j]!=' ')&&(a[j]!='\n'))//所以我们用j复制i的值,用j来打印后面几位元素的值
			{    //while循环,除非a[j]为空格/换行符,否则一直执行循环体,逐个打印空格后面的字符
				printf("%c", a[j++]);
			}
			printf(" ");//用来打印一个单词的循环结束,根据题意需要打印一个空格
		}
	}
	while ((a[i] != ' ') && (a[i] != '\n'))
	{
		printf("%c", a[i++]);
	}
	return 0;
}

五、优化代码
PAT上很多题目被我以前老师拿来给我们布置作业,可惜那个时候我不认真,代码都是网上复制粘贴的。接下来这个代码就是我以前拷贝来的,出处已经找不到了,但我觉得比我写的更有水平,拿出来给大家参考一下。

#include <stdio.h>
int main()
{
	char a[80][80];//定义二维数组,后面会一行存储一个单词
	int i = 0;
	do {
		scanf("%s", a[i++]);//scanf("%s")遇到空白符(空格,tab,\n)会停止接收,并且空格留在输入缓存区中
	} while (getchar()!='\n');//getchar()用于接收空格,当它接收到换行符时说明字符串输入结束,故终止循环
	while (--i)//当前a[i]在最后一个单词所在行的后面一行,是一个空白行,所以需要先自减,再使用i打印最后一个单词,然后依次往前
	{
		printf("%s ",a[i]);
	}
	printf("%s", a[i]);//当i为0时(a[0]为第一个单词所在行)上述循环结束,并没有打印第一个单词,所以在这里打印
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值