请实现一个函数,将字符串中的空格替换成“%20”

一、传统做法

从开始位置向后遍历,如果发现空格,则挪动后面的字符串腾出 2 个字符的空间,写入“%20”,直至到字符串末尾。

(灰色部分是每次要挪动的字符)

这种方法非常直观,但是性能较差。假设字符串长度为 n,其中空格数量为 m,那么时间复杂度大概为 O(m*n),简化为 m = n,那么时间复杂度就变成了 O(n^2) 。

二、高性能做法

为了提高性能,需要尽可能的减少后面字符不必要的挪动次数,即:最后一次就能将后面的字符挪动到最终的位置上,方法就是从后面开始遍历字符串。

为了达到上述目的,需要提前知道空格替换完之后最终的字符串大小。所以开始遍历一遍字符串,假设字符串长度为 n,空格数量为 m,那么空格替换完之后的字符串长度为 len = n + m * 2 。

下一步就是开始搬运字符和替换空格的过程:

假设有两个指针分别指向了原始字符串末尾位置(p1)和最终字符串的末尾位置(p2)。首先要从后向前遍历,查看 p1 指向的字符是否是空格,如果不是的话就将该字符挪到 p2 位置上,由此类推,p1 不断向字符开始位置遍历,直至结束。

上述方法字符串每个字符挪动一次就行了,故时间复杂度为 O(n) 。

三、测试

#include <iostream>
#include <string.h>

void Print(const char *const p);
void ReplayBlank(char *const data, const size_t &len);
void test(const char *const data, const size_t &len);

int main(int argc, char *argv[])
{
    test("I love China", 13);
    test(" I love China ", 15);
    test("I_love_China", 13);
    test("", 0);
    test(" ", 1);
    return 0;
}

void test(const char *const data, const size_t &len)
{
    char *src = new char[len * 2]();
    memcpy(src, data, strlen(data));
    Print(src);
    ReplayBlank(src, strlen(src) + 1);
    Print(src);
    std::cout << "----------------------" << std::endl;
    delete []src;
    return;
}

void Print(const char *const p)
{
    if (p == nullptr)
        return;
    std::cout << p << std::endl;
    return;
}

void ReplayBlank(char *const data, const size_t &len)
{
    if (data == nullptr || len == 0)
        return;
    size_t blank_count = 0;
    int i = 0;
    while (i < len)
    {
        if (data[i] == ' ')
            blank_count++;
        i++;
    }
    if (blank_count == 0)
        return;
    size_t len_all = len + blank_count * 2;
    char *p1 = data + len;
    char *p2 = data + len_all;
    for (i = 0; i <= len; ++i)
    {
        if (*(p1 - i) != ' ')
        {
            *p2 = *(p1 - i);
            p2--;
        }
        else
        {
            *(p2--) = '0';
            *(p2--) = '2';
            *(p2--) = '%';
        }
    }
    return;
}

结果:

I love China
I%20love%20China
----------------------
 I love China 
%20I%20love%20China%20
----------------------
I_love_China
I_love_China
----------------------


----------------------
 
%20
----------------------

注意,代码中要展现出判空、空字符串、没有空格、全是空格等情况的处理。

 

(SAW:Game Over!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值