[题目]:请编写一个函数来颠倒单词在字符串里的出现顺序。例如,将字符串“Do or not do, there is no try.”转换为“try. no is there do, not or Do”假设所有单词都以空格为分隔符,标点符号也当作字符来对待。
对于这类颠倒字符或者单词的处理,我们通常的办法是采用一个临时缓冲区,将识别出来的字符或者单词写道这个缓冲区里,最后把缓冲区的内容拷贝回原来的字符串。
从字符串尾开始逆向扫描,首先让指针扫描到字符“y” ,指针递减,继续扫描到这个单词的第一个字符“t”,将“t”到“y”之间的字符逐个拷贝到临时缓冲区,即将try单词拷贝到缓冲区。然后把空格直接拷贝到缓冲区。当把“D”、“o”拷贝到缓冲区后,不要忘了在临时缓冲区的末尾加上一个‘/0’字符。
void reversewords (char str[])
{
char *buffer;
int tokenreadpos, wordreadpos,wordend,writepos = 0;
tokenreadpos =strlen(str)-1;
buffer = (char *) malloc (tokenreadpos + 2);
if (!buffer)
return NULL;
while(tokenreadpos>=0)
{
if(str[tokenreadpos] ==' ')
buffer[writepos++] = str[tokenreadpos--];
else
{
wordend = tokenreadpos;
while (tolenreadpos>=0 && str[tokenreadpos]!= ' ')
tokenreadpos--;
wordreadpos = tokenreadpos+1;
while(wordreadpos <= wordend)
buffer[writepos++] = str[wordreadpos++];
}
}
buffer[writepos]='/0';
strcpy(str,buffer);
free(buffer);
return str;
}
如果我们不另外分配一个临时缓冲区,还可以完成这个操作么?用交换字符的办法也能对字符串进行颠倒。通过逆转字符,我们首先将字符串转换为“ ytr on si ereht od ton ro oD”,我们只要把颠倒过来的字符串中的每一个单词在颠倒一遍,就能得到我们想要的字符串了。所以,我们只需要写一个对字符串本身进行逆转的函数就能完成任务了。
#include <iostream.h>
#include <string.h>
void ReverseWords (char str[]);
void ReverseString (char str[], int start, int end); //逆转字符串函数
void main()
{
char str[40];
cout<<"请输入一行句子(以回车符结束): ";
cin.getline(str,40); //getline将输入的字符串(可以包含空格)的前39个字符拷贝到str数组中,
ReverseWords(str);
cout<<"输出颠倒单词后的句子: "<<str<<endl;
}
void ReverseWords (char str[])
{
int start=0,end=0,length;
length=strlen(str);
ReverseString(str,start,length-1);
while(end<length)
{
if(str[end]!=' ')
{
start=end;
while(end<length&&str[end]!=' ')
end++;
end--;
ReverseString(str,start,end);
}
end++;
}
return;
}
void ReverseString (char str[],int start,int end)
{
char temp;
while (end>start)
{
temp=str[start];
str[start]=str[end];
str[end]=temp;
start++;
end--;
}
return;
}
运行结果:
请输入一行句子(以回车符结束):Do or not do, there is no try.
输出颠倒单词后的句子:try. no is there do, not or Do