目录
1009:说反话
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
代码长度限制:
16 KB
时间限制
400 ms
内存限制
64 MB
思路:
1.数组
字符串最长为80,我们可以定义一个长度为81的cahr类型数组a.
我们要做的是找a这个字符串里面的单词,单词最为80,最多也为80,我们就可以定义一个char类型二维数组s[81][81],这是来干什么的呢?
前面s[0],s[1]代表的是0号单词和1号单词,s[0][1],s[1][1]代表的是0号单词的1号字母和1号单词的1号字母,也计算说,s这个字符串存的是所有的单词.
存好之后,倒着输出就是反话了!
1.2代码:
for(int i=/*s的长度*/;i>=0;i--){ //循环输出
if(i!=0) //特判
cout<<s[i]<<" "; //输出空格
else
cout<<s[i];//后面不加空格
}
因为题目要求是行末尾,没有空格,所有输出的时候要判断一下.
2.拷贝单词
关键问题就是,怎么把字符串a里面的单词拷贝到字符串s里面.
根据题目要求,每一个空格前后就是两个单词,这样的话,我们可以进行双指针操作,两个指针sum,j.
sum代表的是这个单词的数量,j代表是单词的长度,s[sum][j],两者初始化为0之后,我们可以进行拷贝单词了.
首先用strlen函数求出a的长度t,然后从下标0开始,一直到t-1开始循环遍历,如果不是空格的话,我们就进行s[sum][j]=a[i]的操作,进行之后,将指针j向后挪移一位,相当于j++,这样下次赋值就不会重复了.
那如果碰到空格怎么办呢?sum代表的是单词的个数,喷到空格代表当前的单词已经到了结尾,已经拷贝完成了,就讲单词个数sum++,下一个字符就存到另外一个单词中,不会发生冲突,之后我们还需要将当前单词的长度j设置为0,毕竟都已经下一个单词了,从新开始了!
2.2代码:
void fun(){
int j=0; //当前单词的长度
int t=strlen(a); //求字符串a的长度
for(int i=0;i<t;i++){ //循环遍历
if(a[i]!=' ') //如果不是空格
s[sum][j]=a[i],j++; //进行拷贝,将单词长度j+1
else //如果是空格
sum++,j=0; //将单词数量sum+1,并且将单词长度重新赋值为0
}
}
总代码:
#include<bits/stdc++.h>
using namespace std;
char a[81]; //字符串
char s[81][81]; //单词串
int sum=0;
void fun(){
int j=0; //当前单词的长度
int t=strlen(a); //求字符串a的长度
for(int i=0;i<t;i++){ //循环遍历
if(a[i]!=' ') //如果不是空格
s[sum][j]=a[i],j++; //进行拷贝,将单词长度j+1
else //如果是空格
sum++,j=0; //将单词数量sum+1,并且将单词长度重新赋值为0
}
}
int main(){
cin.getline(a,81); //输入一个长度最大为80的,字符串a
fun(); //将a里面的单词拷贝到s里面
for(int i=sum;i>=0;i--){ //倒序输出单词
if(i!=0) //中间判断
cout<<s[i]<<" "; //输出空格
else //结尾判断
cout<<s[i]; //不输出空格
}
cout<<endl;
return 0;
}
时间复杂度:
时间复杂度为O(N),已经算是非常快的了!
总结:
这道题考了学生们关于双指针,字符串处理的应用,应用双指针,可以非常有效的解决运用双重for循环的巨大时间开销问题,时间优化了不少!