算法_倒置单词

这道题真的难倒过我......

快要期末考试了,时间比较紧,但是真的忍不住不写博客。

据说,写博客会上瘾,似乎体会到了......

那倒是希望上瘾,然后成为一个博客控。

目录

一、问题描述

二、算法分析

三、算法设计

(1)逆序整个字符串

(2)逆序单词

四、代码实现


一、问题描述

将一句话的单词进行倒置,标点不倒置。

比如 I like beijing. 经过函数后变为:beijing. like I

倒置字符串_牛客题霸_牛客网 (nowcoder.com)

二、算法分析

不同于简单逆序,而是虽然顺序变了,但是每个单词还是完整的单词。我们可以将整个字符串逆序,然后再将每个单词逆序一下

再次强调,我们要做的是这两步:

第一步,逆序整个字符串

第二步,逆序每个单词

我们可发现,倒序整个字符串和倒序一个单词的思路大体上是一样,都是从起始位置和结束位置开始逐个一对一对地进行交换。如下图所示,I like beijing.的逆序和like的逆序:

三、算法设计

(1)逆序整个字符串

现定义一个函数,创建两个形参,分别为char* start和char* end,用于记录起始位置和结束位置的字符所在地址。

相应地,这里要把一个字符串的首地址和最后一个字符的地址传递给函数。

字符串首地址用数组名即可,那么末位字符串地址可以用数组名加上字符串长度(可用strlen实现)再减去1。

当传递的地址进入函数内部后进行交换,然后依次让start向右移动,让end向左移动,再交换字符,直到start所指向的字符和end所指向的字符相同时停止交换。

void reverse(char* start, char* end);
char input[100];

gets(input);

reverse(input, input + strlen(input) - 1);

注意不能使用scanf!scanf遇空格结束,要用gets。

接下来用while语句和临时变量实现逆序

while(start < end)
{
char temp = *start;
*start = *end;
*end = temp;

start++;
end--;
}

(2)逆序单词

(事实上,逆序单词和逆序字符串的顺序是可以互换的。

创建两个字符型地址变量,char* cur和char* start,分别记录单词首元字符的地址和末位字符的地址。

调用while函数,条件为当cur所指向地址的字符不为空格并且所指向地址的字符不为\0。

char* cur = arr;
char* start = cur;
while(*cur!=' '&&*cur!='\0')
{
    cur++;
}

先前定义过字符串逆序的函数,在逆序一个单词时同样可调用此函数

当停止循环时,cur指向的是空格,那么在调用函数时就要减去1。

reverse(start,cur-1);

在调用过此函数后,让cur自增,跳过空格

若想继续进行下去,直到每个单词都实现逆序,就要把刚才所写代码嵌套在while语句中,条件为*start,即当start所指向地址的字符不为\0。

while(*start)
{
    char *cur = start;
    while(*cur!=' '&&*cur!='\0')
        cur++;
    reverse(start, cur-1);
    cur++;
}

实际上,代码还没完善,当字符串以空格结尾时,循环就会继续进行下去,所以需要给cur自增添加一个cur所指向的地址的字符不为\0的条件。

while(*start)
{
    char *cur = start;
    while(*cur!=' '&&*cur!='\0')
        cur++;
    reverse(start, cur-1);
    if(*cur!='\0')
        cur++;
}

这样就完美了。

四、代码实现

#include <stdio.h>
#include <string.h>
void reverse(char* start, char* end)
{
    while(start < end)
   {
        char temp = *start;
        *start = *end;
        *end = temp;
        
        start++;
        end--;
   }
}
int main()
{
    char input[100];
    // 注意不能使用scanf,scanf遇到空格,一次输入接收就结束了
    gets(input);
    
    // 翻转整个句子
    reverse(input, input + strlen(input) - 1);
    
    // 翻转单词
    char* start = input;
    while(*start)
   {
        char *cur = start;
        while(*cur != ' ' && *cur!='\0')
            cur++;
        reverse(start, cur-1);
        if(*cur!='\0')
            cur++;
        
   }
    
    printf("%s", input);
    
    return 0;
}

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值