1361--翻转单词顺序

题目描述:
JOBDU最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
输入:
每个测试案例为一行,表示一句英文句子。
我们保证一个句子的单词数不会超过600,每个单词的长度也不会超过30。但是需要注意的是Fish是个不拘小节的人,有时候两个单词中间可能会有很多空格。为了方便起见,你可以认为一行的字符总数不会超过50000个,标点符号可以和普通字母一样处理。
输出:
对应每个测试案例,把翻转后的正确的句子单独输出一行。
样例输入:
student. a am I
I'm a Freshman and I like JOBDU!
样例输出:
I am a student.
JOBDU! like I and Freshman a I'm

///////////////////////////////////////////////////////////////////////
// Reverse a string between two pointers
// Input: pBegin - the begin pointer in a string
//        pEnd   - the end pointer in a string
///////////////////////////////////////////////////////////////////////
void Reverse(char *pBegin, char *pEnd)
{
      if(pBegin == NULL || pEnd == NULL)
            return;

      while(pBegin < pEnd)
      {
            char temp = *pBegin;
            *pBegin = *pEnd;
            *pEnd = temp;

            pBegin ++, pEnd --;
      }
}

///////////////////////////////////////////////////////////////////////
// Reverse the word order in a sentence, but maintain the character
// order inside a word
// Input: pData - the sentence to be reversed
///////////////////////////////////////////////////////////////////////
char* ReverseSentence(char *pData)
{
      if(pData == NULL)
            return NULL;

      char *pBegin = pData;
      char *pEnd = pData;

      while(*pEnd != '\0')
            pEnd ++;
      pEnd--;

      // Reverse the whole sentence
      Reverse(pBegin, pEnd);

      // Reverse every word in the sentence
      pBegin = pEnd = pData;
      while(*pBegin != '\0')
      {
            if(*pBegin == ' ')
            {
                  pBegin ++;
                  pEnd ++;
                  continue;
            }
            // A word is between with pBegin and pEnd, reverse it
            else if(*pEnd == ' ' || *pEnd == '\0')
            {
                  Reverse(pBegin, --pEnd);
                  pBegin = ++pEnd;
            }
            else
            {
                  pEnd ++;
            }
      }

      return pData;
}

  


解题思路:
由于本题需要翻转句子,我们先颠倒句子中的所有字符。这时,不但翻转了句子中单词的顺序,而且单词内字符也被翻转了。我们再颠倒每个单词内的字符。由于单词内的字符被翻转两次,因此顺序仍然和输入时的顺序保持一致。
还是以上面的输入为例子。翻转“I am a student.”中所有字符得到“.tneduts a ma I”,再翻转每个单词中字符的顺序得到“students. a am I”,正是符合要求的输出。
AC代码:
#include<iostream>
#include<stdio.h>
using namespace std;
char s[50002];
int main()
{
	void Reserve(char *pBegin,char *pEnd);
	void ReserveSentence(char *pData);
	while(gets(s))
	{
		ReserveSentence(s);
		for(int i=0;s[i]!='\0';i++)
			cout<<s[i];
		cout<<endl;
	}
	return 0;
}

// Reverse a string between two pointers
// Input: pBegin - the begin pointer in a string
//        pEnd   - the end pointer in a string
void Reserve(char *pBegin,char *pEnd)
{
	if(pBegin==NULL || pEnd==NULL ) return;
	while(pBegin<pEnd)
	{
		char temp=*pBegin;
		*pBegin=*pEnd;
		*pEnd=temp;
		pBegin++;
		pEnd--;
	}
}

// Reverse the word order in a sentence, but maintain the character order inside a word
// Input: pData - the sentence to be reversed

void ReserveSentence(char *pData)
{
	char *pBegin,*pEnd;
	pBegin=pData;
	pEnd=pData;
	while(*pEnd!='\0') pEnd++;
	pEnd--;
	// Reverse the whole sentence
	Reserve(pBegin,pEnd);
	// Reverse every word in the sentence
	pBegin=pEnd=pData;
	while(*pBegin!='\0')
	{
		if(*pBegin==' ')
		{
			pBegin++;
			pEnd++;
			continue;
		}
		else if(*pEnd==' '||*pEnd=='\0')
		{
			Reserve(pBegin,--pEnd);
			pBegin=++pEnd;
		}
		else
		{
			pEnd++;
		}
	}
}

  之前一直WRONG ,原因是输入字符串时使用的是‘cin’---自动地默认某一字符串的结束符是空格键;(字符串中不能有空格键)

                                                                    gets---字符串中可以包含空格键,当输入换行键时,才认为此字符串结束(字符串中可以包含空格)

gets  需要包含头文件----#include<stdio.h>

这个问题之前有出现过,但是又忘记了!!!!悲剧

posted @ 2015-01-04 15:37  zhoudan  阅读(127)  评论(0)    收藏  举报