PAT乙级 1009 说反话 (20分) (题目 + 代码 + 详细注释 + 两种方法实现)

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子。

输入样例:

Hello World Here I Come

输出样例:

Come I Here World Hello

常规思路:读入字符串,从头开始得到每一个单词并储存,然后逆序输出即可

法一(参考“算法笔记”):由于本题是单点测试(即只有一组输入数组),所以输入会以EOF结尾。用scanf读字符串,每次读到空格即停止,此时都得到的就是一个单词,将其储存在二维数组中,再逆序输出即可。本法虽然也是常规思路,但是利用了scanf的特点,更加简洁了些

直接上代码吧:

#include<cstdio>
using namespace std;

int main(){
    int cnt = 0;    //cnt为读入的单词个数
    char ans[80][80];   //二维数组ans储存读入的单词
    while(~scanf("%s", ans[cnt]))     //判断scanf返回值是否是EOF(即是否输入完毕)
        cnt++;      //单词个数+1 

    while (cnt--)           //逆序输出单词
    	printf("%s%s", ans[cnt], cnt > 0 ? " " : "");   //最后一个单词后无空格
  
    return 0;
} 

法二:“将计就计”,既然要逆序输出字符串, 那么我就从后往前看

           思路:用gets一次性读入整个字符串,倒着遍历, 每次找到空格时,就输出该空格后面的单词,然后将这个单词抹掉(巧妙之处:把该空格改为结束符'\0'),直到遍历到字符串头。就像从后往前砍一根木棍,每次砍断一截,直到砍完为止,每次砍的刀痕就是'\0'。

下面是AC的代码:

#include<stdio.h>
#include<string.h>

#define MAX 82

int main() {
	int n, k, i;
	char s[MAX];
	gets(s);      //读入字符串
	n = strlen(s);       //得到字符串长度
	char* p = s + n;        //p指针开始时指向字符串尾('\0'的位置)
	while (1) {               //条件没什么好写的,干脆写个1, 循环里面有终止条件(自我喜好)
		if (p == s) {           //p == s说明到达了字符串头,则终止循环
			printf("%s\n", p);        //输出该单词
			break;               //跳出循环
		}
		else if (*p == ' ' && *(p + 1) != ' ') {        //找到空格,并且其后不是空格(即是单词)
			*p = '\0';        //把空格处换成结束符'\0'
			printf("%s ", p + 1);     //输出该空格后面的单词
		}
		p--;    //倒着遍历,指针向左移动一个
	}

	return 0;
}

//总结:自我认为两种方法都是非常巧妙的(不喜莫见怪啊!),但是感觉第二种方法更有技术性,更为推荐

猜你喜欢

转载自blog.csdn.net/qq_45472866/article/details/104397617
今日推荐