首页 > 代码库 > Reverse Words in a String

Reverse Words in a String

Problem:

Given an input string, reverse the string word by word.

For example,

Given s = "the sky is blue",

return "blue is sky the".

这个题目叙述的不够精确,有些边界的情况需要考虑。题目的下方给出了Clarification澄清了几个问题,也是面试的时候需要确认的。

第一个问题是什么构成了一个词(word),回答是一串不包含空格(non-space)的字符。这里需要理解non-space,应该要包含‘ ‘, ‘\t‘, ‘\n‘等字符,C语言中可以通过宏定义isspace来判断。

第二个问题是词的开头与结尾能有空格吗,回答是有的,但返回的结果中应该去掉。

第三个问题是分隔每两个词之间的空格能有多个吗,回答是能,但返回结果中应该只留下一个空格就好。

通过询问这三个问题,题目也就清楚多了,这个题目的解决思路并不困难,就是先翻转每个单词,再对整个字符串翻转就能做到翻转每个单词的目的,但是同时要想将单词间的空格变为一个,头尾都要去掉就要费一番功夫。

我的解法是直接在原始的字符串上一遍扫描,从后向前翻转单词,同时将单词移位到正确的位置,即每两个单词之间保证只有一个空格。然后整体再翻转一次,只有结尾处还可能有些空格,再单独处理。代码中使用了algorithm中的reverse来翻转字符串,效率可能会稍差,可以自己直接用下标操作,写个翻转函数。

 1 void reverseWords(string &s) {
 2         int len = s.length();
 3 
 4         // find each word iteratively and then reserve it
 5         int align = len-1;
 6         int start_pos, end_pos;
 7         for(int i = len-1; i >= 0; --i) {
 8             if(!isspace(s[i])) {
 9                 end_pos = i;
10                 
11                 while(i >= 0 && !isspace(s[i])) {
12                     --i;
13                 }
14                 start_pos = i+1;
15      
16                 reverse(s.begin()+start_pos, s.begin()+end_pos+1);
17                 
18                 if(end_pos != align) {
19                     for(int j = 0; j <= end_pos-start_pos; ++j) {
20                         s[align-j] = s[end_pos-j];
21                     }
22                 }
23                 align -= (end_pos-start_pos+1);
24                 if(align >= 0) {
25                     s[align--]=  ;
26                 }
27             }
28         }
29     
30         if(align >= 0) {
31             fill(s.begin(), s.begin()+align+1,  );
32         }
33         
34         // reverse the whole string and trim the leading and trailing spaces
35         reverse(s.begin(), s.end());
36     
37         int i = len-1;
38         while(i >= 0 && isspace(s[i]))
39             --i;
40         s = s.substr(0, i+1);
41     }