[关闭]
@weixin 2015-01-20T22:33:50.000000Z 字数 6845 阅读 1217

reverse word in a string

leetcode


question

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

solution 1 - by using extra space as stack

version 1

  1. class Solution
  2. {
  3. public:
  4. void reverseWords(string &s)
  5. {
  6. vector<string> stack;
  7. string temp_s;
  8. bool w_boundary = false;
  9. for( int i = 0; i < s.length(); i++)
  10. {
  11. char c = s[i];
  12. // starting space need to ignre
  13. if( isspace(c) && !w_boundary)
  14. {
  15. continue;
  16. }
  17. // if it is the first space after a word
  18. else if(isspace(c) && w_boundary)
  19. {
  20. // need to push the word to stack
  21. stack.push_back(temp_s);
  22. // clear the temp string prepare for the next loop
  23. temp_s.clear();
  24. // push a space to sperator
  25. stack.push_back(" ");
  26. // reset it to be false, it goes to the above if block
  27. // extra space would be ignored
  28. w_boundary = false;
  29. }
  30. else if( isalnum(c) )
  31. {
  32. if(!w_boundary)
  33. {
  34. w_boundary = true;
  35. }
  36. temp_s += c;
  37. }
  38. }
  39. // cleare the origina string
  40. s.clear();
  41. while(!stack.empty())
  42. {
  43. s.append(stack.back());
  44. stack.pop_back();
  45. }
  46. }
  47. };

result :

Input: "a"
Output: ""
Expected: "a"

version 2

  1. class Solution
  2. {
  3. public:
  4. void reverseWords(string &s)
  5. {
  6. vector<string> stack;
  7. string temp_s;
  8. bool w_boundary = false;
  9. for( int i = 0; i < s.length(); i++)
  10. {
  11. char c = s[i];
  12. // starting space need to ignre
  13. if( isspace(c) && !w_boundary)
  14. {
  15. continue;
  16. }
  17. // if it is the first space after a word
  18. else if(isspace(c) && w_boundary)
  19. {
  20. // need to push the word to stack
  21. stack.push_back(temp_s);
  22. // clear the temp string prepare for the next loop
  23. temp_s.clear();
  24. // push a space to sperator
  25. stack.push_back(" ");
  26. // reset it to be false, it goes to the above if block
  27. // extra space would be ignored
  28. w_boundary = false;
  29. }
  30. else if( isalnum(c) )
  31. {
  32. if(!w_boundary)
  33. {
  34. w_boundary = true;
  35. }
  36. temp_s += c;
  37. if(i==s.length()-1)
  38. {
  39. stack.push_back(temp_s);
  40. }
  41. }
  42. }
  43. // cleare the origina string
  44. s.clear();
  45. while(!stack.empty())
  46. {
  47. s.append(stack.back());
  48. stack.pop_back();
  49. }
  50. }
  51. };

after adding this code :

if(i==s.length()-1) {
stack.push_back(temp_s); }

result :
此处输入图片的描述

version 3

  1. vector<string> stack;
  2. string temp_s;
  3. bool w_boundary = false;
  4. for( int i = 0; i < s.length(); i++)
  5. {
  6. char c = s[i];
  7. // starting space need to ignre
  8. if( isspace(c) && !w_boundary)
  9. {
  10. // if there is trailing space
  11. // the below code would push an extra space
  12. // should be poped here
  13. if(i==s.length()-1)
  14. {
  15. stack.pop_back();
  16. }
  17. continue;
  18. }
  19. // if it is the first space after a word
  20. else if(isspace(c) && w_boundary)
  21. {
  22. // need to push the word to stack
  23. stack.push_back(temp_s);
  24. // clear the temp string prepare for the next loop
  25. temp_s.clear();
  26. // push a space to sperator
  27. stack.push_back(" ");
  28. // reset it to be false, it goes to the above if block
  29. // extra space would be ignored
  30. w_boundary = false;
  31. }
  32. else if( isalnum(c) )
  33. {
  34. if(!w_boundary)
  35. {
  36. w_boundary = true;
  37. }
  38. temp_s += c;
  39. if(i==s.length()-1)
  40. {
  41. stack.push_back(temp_s);
  42. }
  43. }
  44. }
  45. // cleare the origina string
  46. s.clear();
  47. while(!stack.empty())
  48. {
  49. s.append(stack.back());
  50. stack.pop_back();
  51. }
  52. }

result :

runtime error
Last executed input: " "

version 4

  1. vector<string> stack;
  2. string temp_s;
  3. bool w_boundary = false;
  4. for( int i = 0; i < s.length(); i++)
  5. {
  6. char c = s[i];
  7. // starting space need to ignre
  8. if( isspace(c) && !w_boundary)
  9. {
  10. // if there is trailing space
  11. // the below code would push an extra space
  12. // should be poped here
  13. if(i==s.length()-1&&!stack.empty())
  14. {
  15. stack.pop_back();
  16. }
  17. continue;
  18. }
  19. // if it is the first space after a word
  20. else if(isspace(c) && w_boundary)
  21. {
  22. // need to push the word to stack
  23. stack.push_back(temp_s);
  24. // clear the temp string prepare for the next loop
  25. temp_s.clear();
  26. // push a space to sperator
  27. if(i!=s.length()-1)
  28. {
  29. stack.push_back(" ");
  30. }
  31. // reset it to be false, it goes to the above if block
  32. // extra space would be ignored
  33. w_boundary = false;
  34. }
  35. else if( isalnum(c) )
  36. {
  37. if(!w_boundary)
  38. {
  39. w_boundary = true;
  40. }
  41. temp_s += c;
  42. if(i==s.length()-1)
  43. {
  44. stack.push_back(temp_s);
  45. }
  46. }
  47. }
  48. // cleare the origina string
  49. s.clear();
  50. while(!stack.empty())
  51. {
  52. s.append(stack.back());
  53. stack.pop_back();
  54. }
  55. }

result:

Input: "hi!"
Output: ""
Expected: "hi!"

version 5

  1. void reverseWords(string &s)
  2. {
  3. vector<string> stack;
  4. string temp_s;
  5. bool w_boundary = false;
  6. for( int i = 0; i < s.length(); i++)
  7. {
  8. char c = s[i];
  9. // starting space need to ignre
  10. if( isspace(c) && !w_boundary)
  11. {
  12. // if there is trailing space
  13. // the below code would push an extra space
  14. // should be poped here
  15. if(i==s.length()-1&&!stack.empty())
  16. {
  17. stack.pop_back();
  18. }
  19. continue;
  20. }
  21. // if it is the first space after a word
  22. else if(isspace(c) && w_boundary)
  23. {
  24. // need to push the word to stack
  25. stack.push_back(temp_s);
  26. // clear the temp string prepare for the next loop
  27. temp_s.clear();
  28. // push a space to sperator
  29. if(i!=s.length()-1)
  30. {
  31. stack.push_back(" ");
  32. }
  33. // reset it to be false, it goes to the above if block
  34. // extra space would be ignored
  35. w_boundary = false;
  36. }
  37. else if( isword(c) )
  38. {
  39. if(!w_boundary)
  40. {
  41. w_boundary = true;
  42. }
  43. temp_s += c;
  44. if(i==s.length()-1)
  45. {
  46. stack.push_back(temp_s);
  47. }
  48. }
  49. }
  50. // cleare the origina string
  51. s.clear();
  52. while(!stack.empty())
  53. {
  54. s.append(stack.back());
  55. stack.pop_back();
  56. }
  57. }
  58. bool isword( char c )
  59. {
  60. return !isspace( c ) && !iscntrl( c );
  61. }

finally passed<, but the speed is not that good.

此处输入图片的描述

solution 2 - directly do it in place.

"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:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <sstream>
  4. #include <vector>
  5. #include <stack>
  6. #include <queue>
  7. #include <deque>
  8. #include <unordered_set>
  9. #include <unordered_map>
  10. #include <list>
  11. #include <map>
  12. #include <string>
  13. #include <cstring>
  14. #include <algorithm>
  15. #include <climits>
  16. #include <cctype>
  17. #include <utility>
  18. #include <functional>
  19. #include <iterator>
  20. using namespace std;
  21. class Solution
  22. {
  23. public:
  24. void reverseWords(string &s)
  25. {
  26. if(s.length()==0)
  27. {
  28. return;
  29. }
  30. // 2 pointers
  31. int prev =0, next= 0;
  32. // remove the leading space
  33. while(isspace(s[prev]))
  34. {
  35. // this is wrong to increment it, you start remove from start
  36. // after remove one, you still need to stay at start
  37. //s.erase(prev++,1);
  38. s.erase(prev,1);
  39. }
  40. // remove the trailing space
  41. next = s.length() - 1;
  42. while(isspace(s[next]))
  43. {
  44. s.erase(next--,1);
  45. }
  46. // reset the pointers
  47. prev=next=0;
  48. while(next != s.length())
  49. {
  50. // detect the word boundary, until the next pointer goes to a space
  51. while(next<s.length()&&!isspace(s[next]))
  52. {
  53. next++;
  54. }
  55. // reverse the word
  56. reverse(s.begin() + prev, s.begin() + next);
  57. if(next == s.length())
  58. {
  59. break;
  60. }
  61. // erase the additional space between word
  62. // need to keep one space
  63. next++;
  64. while(next<s.length()&&isspace(s[next]))
  65. {
  66. s.erase(next,1);
  67. }
  68. // prev the new start of the word
  69. prev = next;
  70. }
  71. // the revese the whole sentense
  72. reverse(s.begin(),s.end());
  73. }
  74. };
  75. int main()
  76. {
  77. Solution sol;
  78. string s = " this is the blue sky hot ";
  79. // string s = " this is the blue ";
  80. string s2= " a b ";
  81. string s3 = "a ";
  82. string s4 = " ";
  83. string s5 = "hi!";
  84. string s6 ="b ";
  85. string s7 ="";
  86. string s8 ="ab";
  87. sol.reverseWords( s );
  88. cout <<"."<< s <<"." <<endl;
  89. sol.reverseWords( s2 );
  90. cout << s2 <<endl;
  91. sol.reverseWords( s3 );
  92. cout << s3 <<endl;
  93. sol.reverseWords(s4);
  94. cout << s4 <<endl;
  95. sol.reverseWords(s5);
  96. cout << s5 <<endl;
  97. sol.reverseWords(s6);
  98. cout << s6 <<endl;
  99. sol.reverseWords(s7);
  100. cout << s7 <<endl;
  101. sol.reverseWords(s8);
  102. cout << s8 <<endl;
  103. return 0;
  104. }

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 :
13ms

just 13ms. a lot better.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注