题目:翻转单词序列
描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“nowcoder. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a nowcoder.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
解题思路:在题目中,我们可以看到,最终结果为将每个单词翻转过来,但是其内部每个字母的位置是不发生改变的。根据这个原理,我们进行具体方法的解读。
在具体方法中,我们可以将原来的句子先实现翻转,翻转的过程为在整句话的首尾端各放置一个指针,通过交换指针所指的数字,将两个指针不断的往中间移动即可完成交换,之后,通过空格的位置,对每个单词使用同样的方法翻转即可。
具体解题步骤如下:
在输入端输入:"nowcoder. a am I"
nowcoder. | a | am | i |
首先将各个字母实现翻转 | |||
i | ma | a | .redocwon |
其次将对每个单词内部字母实现翻转 | |||
i | am | a | Nowcoder. |
最终输出的就是最后的结果 |
具体C++代码如下所示:(其中交换函数的代码我们必须要理解记住)
class Solution { public: string ReverseSentence(string str) { int len = str.size(); if (len == 0) return ""; for(int i = 0; i < len; ++i) if(str[i] != ' '){ int begin = i,end = i; while(end < len && str[end] != ' ') end++; end == len - 1?i = end: i = --end; myReverse(str, begin, end); } myReverse(str, 0, len - 1); return str; } void myReverse(string &str, int begin, int end){//内部交换函数 int len = str.size();//字符串长度 if(begin < 0 || end >= len)//begin和end仅仅指的是下标 return; while(begin < end){ char temp = str[begin]; str[begin] = str[end]; str[end] = temp; begin++;end--; } } };在这种算法中,应该要熟记该解题方法,左移,右移等一些移动策略,可以严格按照该模式,进行书写。
另一种方法:我们需要从前往后进行遍历,当遇到空格后,就把之前读取的值压到结果的前面并添加空格。最后,当循环结束,如果用来读取字符串的字符不为空的话,就将它压到结果的前面(这次操作不需要加空格)。
具体解题步骤如下所示:
nowcoder. | a | am | i |
nowcoder.后有空格的话,将nowcoder.压到结果值的前面,并添加空格值,如下一步所示 | |||
|
|
| nowcoder. |
逐步进行循环,第二步结果如下 | |||
|
| a | nowcoder. |
第三步结果如下 | |||
| am | a | nowcoder. |
最后一步,当读取字符串的字符不为空,则不需要添加空格 | |||
i | am | a | nowcoder. |
结果如上所示 |
具体C++代码如下所示:
class Solution { public: string ReverseSentence(string str) { string res = "", tmp = ""; for(int i = 0; i < str.size(); ++i){ if(str[i] == ' ') { res = " " + tmp + res;//遇到空格之后将之前读到的结果压到前面并添加空格 tmp = ""; } else tmp += str[i]; } if(tmp.size()) res = tmp + res; return res; } };当遇到重新排序的问题,我们可以直接创建一个空的容器,将原来的东西按照题目的要求直接存放,简单好理解。