题目:翻转单词序列
描述
牛客最近来了一个新员工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;
}
}; 当遇到重新排序的问题,我们可以直接创建一个空的容器,将原来的东西按照题目的要求直接存放,简单好理解。
京公网安备 11010502036488号