题目:
Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue
",
return "blue is sky the
".
思路:
方法1:首先把句子看做由词组成的,从句子中的第一个单词开始,将每个单词的字符逆置,完了后再将整个句子看成都是由字符组成并从头到尾逆置,然后输出即可。整个过程的时间复杂度为O(n),空间复杂度为O(1)。这种方法的缺点是没有考虑许多特殊情况,例如字符串中有连续的空格,字符串开始结尾处有空格等。
方法2:利用两个stack,一个表示单词,一个表示句子。当遇到非空格字符时放入单词stack;当遇到空格时将单词stack中的字符压入句子stack中(注意:单词此时已经逆序一次),然后仅添加一个空格。最后将句子stack依次输出,此时句子逆序。两次逆序的道理同方法1.
代码:
方法1:#include <iostream>
#include <string>
using namespace std;
class ReverseStr
{
public:
void reverseWords(string &s)
{
int begin = 0;
int end = 0;
while (end < (int)s.size())
{
if (s[end] == ' ')
{
swapString(s, begin, end - 1);
begin = end + 1;
end = begin; //将begin和end调到下个单词位置
}
else
{
end++;
}
}
swapString(s, begin, end - 1); //最后一个单词的逆置
swapString(s, 0, s.size() - 1);//再从头到尾逆置
}
void swapString(string &s, int begin, int end)
{
while (end > begin)
{
char c = s[begin];
s[begin] = s[end];
s[end] = c;
begin++;
end--;
}
}
};
int main()
{
string str = "All the things in their being are good for sonething!";
cout << "原单词顺序:"<< str << endl;
ReverseStr rstr;
rstr.reverseWords(str);
cout << "单词逆置后:" << str << endl;
return 0;
}
#include <iostream>
#include <string>
#include <stack>
using namespace std;
class ReverseStr
{
public:
void reverseWords(string &s)
{
stack<int> word;
stack<int> sentence;
int i = 0;
while (i <= (int)s.size())
{
if (i == s.size() || s[i] == ' ')//遇见空格时将栈word中的字符入栈到sentence栈
{
if (!word.empty())
{
if (!sentence.empty()) //判断sentence栈不为空时,加空格
{
sentence.push(' ');
}
while (!word.empty())
{
sentence.push(word.top());// 将栈word中的字符入栈到sentence栈
word.pop(); // word栈中单词(每个字符)出栈
}
}
}
else
{
word.push(s[i]);
}
i++;
}
s.clear();
while (!sentence.empty()) //将sentence栈中字符全部加载到s中
{
s.push_back(sentence.top());
sentence.pop();
}
}
};
int main()
{
string str = "All the things in their being are good for sonething!";
cout << "原单词顺序:" << str << endl;
ReverseStr rstr;
rstr.reverseWords(str);
cout << "单词逆置后:" << str << endl;
return 0;
}
运行结果: