题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路
声明一个函数Reverse实现翻转一个单词,一个函数ReverseSentence翻转整个句子再翻转句子中每个单词
1.声明前后两游标,后游标移至句子中最后一个字符(结束字符前的那个字符)
2.翻转整个句子,前后游标复位至句首
3.遍历整个句子(只要前游标不指向结束字符):
(1)如果前游标指向空格,前后游标继续后移;
(2)如果前游标指向字符,继续移动后游标直至其指向空格(此时选中了一个单词),然后翻转该单词,并准备翻转下个单词
(3)否则(两游标均指向空格),前后游标均后移
代码
class Solution {
public:
string ReverseSentence(string str) {
//检验有效性
if(str.empty())
return str;
int pBegin = 0;
int pEnd = 0;
//后游标移至尾字符
while(str[pEnd] != '\0')
++pEnd;
--pEnd;
//翻转整个字符串
Reverse(str, pBegin, pEnd);
//两游标复位至字符首
pBegin = pEnd = 0;
//翻转每个单词,前后指针从头开始遍历字符串
while(str[pBegin] != '\0')
{
//如果前游标指向空格(单词中间),两游标后移
if(str[pBegin] == ' ')
{
++pBegin;
++pEnd;
}
//前游标指向单词,后游标指向空格(遍历完一个单词)或结束字符
else if(str[pEnd] == ' ' || str[pEnd] == '\0')
{
//翻转游标中间的字符
Reverse(str, pBegin, --pEnd);
//然后两游标准备指向下一单词
pBegin = ++pEnd;
}
//后游标未遍历完一个单词,继续++
else
pEnd++;
}
return str;
}
private:
void Reverse(string& myStr, int begin, int end)
{
if(begin < 0 || end < 0)
return;
//swap
while(begin < end)
{
char temp = myStr[begin];
myStr[begin] = myStr[end];
myStr[end] = temp;
//前后游标缩进
begin++;
end--;
}
}
};