我们先来看题目,这道题目来自于牛客网。

首先我们需要将整个字符串先翻转一边,但这样字符串里面的单词的顺序也就改变了,所以之后我们需要将翻转后的字符串进行局部翻转。

以"the sky is blue"为例。第一遍翻转后字符串变成了"eulb si yks eht"。

之后我们将其中的单词进行局部翻转,就能得到"blue is sky the"。

那我们就要将字符串拆分成一个一个单词,对每一个单词进行翻转。先对"eulb"进行处理,然后再对后面的单词处理。

接下来先看代码

#include<stdio.h>
#include <string.h>
#include <assert.h>
void revolve(char* p1, char* p2)
{
    assert(p1 && p2);
    while (p1 < p2)
    {
        char w = *p1;
        *p1 = *p2;
        *p2 = w;
        p1++;
        p2--;
    }
}
int main()
{
    char str[100];
    gets(str);
    int sz = strlen(str);
    revolve(str, str + sz - 1);
    char* p = str;
    while (*p)
    {
        char* start = p;
        while (*p != ' ' && *p != '\0')
        {
            p++;
        }
        revolve(start, p - 1);
        if (*p == ' ')
        {
            p++;
        }
    }
    printf("%s", str);
}

首先使用gets函数从键盘上读取一段字符串。gets函数会一直读取直到遇到'\n'。但不会将'\n'读入数组。然后写一个翻转函数revolve,revolve的参数设为两个char*的地址,使用指针来交换字符。

将字符串整体翻转后,接下来就是将每个单词分别翻转。使用*p作为循环的结束条件,当*p为'\0'时就会结束。每个单词之间都是以空格作为分界,所以当*p是空格时,就读完了一个单词。

接下来就是将这个单词的首字母地址和末尾地址传给revolve,将单词翻转过来。

这里传末尾地址时需要减一,因为此时这个地址指向的是空格。地址减一就是单词的最后一个字母。

后面的if语句用来判断*p指向的是不是空格,如果是则跳过此空格,如果是'\0',则不跳过,因为循环是用*p来决定是否继续循环,如果跳过了'\0'可能会有问题发生。

最后打印出翻转后的字符串就行。

更多推荐

C语言三步翻转法