@weixin
        
        2015-01-20T22:33:50.000000Z
        字数 6845
        阅读 1399
    leetcode
Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue",
return "blue is sky the".click to show clarification.
Clarification:
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
Show Tags
class Solution{public:void reverseWords(string &s){vector<string> stack;string temp_s;bool w_boundary = false;for( int i = 0; i < s.length(); i++){char c = s[i];// starting space need to ignreif( isspace(c) && !w_boundary){continue;}// if it is the first space after a wordelse if(isspace(c) && w_boundary){// need to push the word to stackstack.push_back(temp_s);// clear the temp string prepare for the next looptemp_s.clear();// push a space to speratorstack.push_back(" ");// reset it to be false, it goes to the above if block// extra space would be ignoredw_boundary = false;}else if( isalnum(c) ){if(!w_boundary){w_boundary = true;}temp_s += c;}}// cleare the origina strings.clear();while(!stack.empty()){s.append(stack.back());stack.pop_back();}}};
result :
Input: "a"
Output: ""
Expected: "a"
class Solution{public:void reverseWords(string &s){vector<string> stack;string temp_s;bool w_boundary = false;for( int i = 0; i < s.length(); i++){char c = s[i];// starting space need to ignreif( isspace(c) && !w_boundary){continue;}// if it is the first space after a wordelse if(isspace(c) && w_boundary){// need to push the word to stackstack.push_back(temp_s);// clear the temp string prepare for the next looptemp_s.clear();// push a space to speratorstack.push_back(" ");// reset it to be false, it goes to the above if block// extra space would be ignoredw_boundary = false;}else if( isalnum(c) ){if(!w_boundary){w_boundary = true;}temp_s += c;if(i==s.length()-1){stack.push_back(temp_s);}}}// cleare the origina strings.clear();while(!stack.empty()){s.append(stack.back());stack.pop_back();}}};
after adding this code :
if(i==s.length()-1) {
stack.push_back(temp_s); }
result : 

vector<string> stack;string temp_s;bool w_boundary = false;for( int i = 0; i < s.length(); i++){char c = s[i];// starting space need to ignreif( isspace(c) && !w_boundary){// if there is trailing space// the below code would push an extra space// should be poped hereif(i==s.length()-1){stack.pop_back();}continue;}// if it is the first space after a wordelse if(isspace(c) && w_boundary){// need to push the word to stackstack.push_back(temp_s);// clear the temp string prepare for the next looptemp_s.clear();// push a space to speratorstack.push_back(" ");// reset it to be false, it goes to the above if block// extra space would be ignoredw_boundary = false;}else if( isalnum(c) ){if(!w_boundary){w_boundary = true;}temp_s += c;if(i==s.length()-1){stack.push_back(temp_s);}}}// cleare the origina strings.clear();while(!stack.empty()){s.append(stack.back());stack.pop_back();}}
result :
runtime error
Last executed input: " "
vector<string> stack;string temp_s;bool w_boundary = false;for( int i = 0; i < s.length(); i++){char c = s[i];// starting space need to ignreif( isspace(c) && !w_boundary){// if there is trailing space// the below code would push an extra space// should be poped hereif(i==s.length()-1&&!stack.empty()){stack.pop_back();}continue;}// if it is the first space after a wordelse if(isspace(c) && w_boundary){// need to push the word to stackstack.push_back(temp_s);// clear the temp string prepare for the next looptemp_s.clear();// push a space to speratorif(i!=s.length()-1){stack.push_back(" ");}// reset it to be false, it goes to the above if block// extra space would be ignoredw_boundary = false;}else if( isalnum(c) ){if(!w_boundary){w_boundary = true;}temp_s += c;if(i==s.length()-1){stack.push_back(temp_s);}}}// cleare the origina strings.clear();while(!stack.empty()){s.append(stack.back());stack.pop_back();}}
result:
Input: "hi!"
Output: ""
Expected: "hi!"
void reverseWords(string &s){vector<string> stack;string temp_s;bool w_boundary = false;for( int i = 0; i < s.length(); i++){char c = s[i];// starting space need to ignreif( isspace(c) && !w_boundary){// if there is trailing space// the below code would push an extra space// should be poped hereif(i==s.length()-1&&!stack.empty()){stack.pop_back();}continue;}// if it is the first space after a wordelse if(isspace(c) && w_boundary){// need to push the word to stackstack.push_back(temp_s);// clear the temp string prepare for the next looptemp_s.clear();// push a space to speratorif(i!=s.length()-1){stack.push_back(" ");}// reset it to be false, it goes to the above if block// extra space would be ignoredw_boundary = false;}else if( isword(c) ){if(!w_boundary){w_boundary = true;}temp_s += c;if(i==s.length()-1){stack.push_back(temp_s);}}}// cleare the origina strings.clear();while(!stack.empty()){s.append(stack.back());stack.pop_back();}}bool isword( char c ){return !isspace( c ) && !iscntrl( c );}
finally passed<, but the speed is not that good.

"this is the blue sky"
but be aware of that we need to remove the leading and traling space
Here is the my latest code:
#include <iostream>#include <stdio.h>#include <sstream>#include <vector>#include <stack>#include <queue>#include <deque>#include <unordered_set>#include <unordered_map>#include <list>#include <map>#include <string>#include <cstring>#include <algorithm>#include <climits>#include <cctype>#include <utility>#include <functional>#include <iterator>using namespace std;class Solution{public:void reverseWords(string &s){if(s.length()==0){return;}// 2 pointersint prev =0, next= 0;// remove the leading spacewhile(isspace(s[prev])){// this is wrong to increment it, you start remove from start// after remove one, you still need to stay at start//s.erase(prev++,1);s.erase(prev,1);}// remove the trailing spacenext = s.length() - 1;while(isspace(s[next])){s.erase(next--,1);}// reset the pointersprev=next=0;while(next != s.length()){// detect the word boundary, until the next pointer goes to a spacewhile(next<s.length()&&!isspace(s[next])){next++;}// reverse the wordreverse(s.begin() + prev, s.begin() + next);if(next == s.length()){break;}// erase the additional space between word// need to keep one spacenext++;while(next<s.length()&&isspace(s[next])){s.erase(next,1);}// prev the new start of the wordprev = next;}// the revese the whole sentensereverse(s.begin(),s.end());}};int main(){Solution sol;string s = " this is the blue sky hot ";// string s = " this is the blue ";string s2= " a b ";string s3 = "a ";string s4 = " ";string s5 = "hi!";string s6 ="b ";string s7 ="";string s8 ="ab";sol.reverseWords( s );cout <<"."<< s <<"." <<endl;sol.reverseWords( s2 );cout << s2 <<endl;sol.reverseWords( s3 );cout << s3 <<endl;sol.reverseWords(s4);cout << s4 <<endl;sol.reverseWords(s5);cout << s5 <<endl;sol.reverseWords(s6);cout << s6 <<endl;sol.reverseWords(s7);cout << s7 <<endl;sol.reverseWords(s8);cout << s8 <<endl;return 0;}
2 things need to be noticed:
if(next == s.length())
{
break;
}
you can not miss this code, assume you have  
" this  is blue " 
after remove leading and trailing space, u would get : 
"this   is blue" 
when prev -> 'b', next -> 'e' , next pointer already reache the end of string, at line 57, next++ again, next currently = s.length(), if there is no such a check, then the code would go to 67, then 73, and fall into a infinite loop.
here is the new result : 

just 13ms. a lot better.