《剑指offer》—— 替换空格

题目

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy.

背景

在网络编程中,如果URL参数中含有特殊字符,如空格、#等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符。转换的规则是在%后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换成%20。再比如 # 的ASCII码为35,即十六进制的0x23,它在URL中被替换为%23.

初始思路

这个是我想出来的单指针法,首先先遍历一次字符串,获得空格的个数,然后根据空格的个数确定改变之后的字符串的长度!
首先我定义了两个len用来获取关检位置的指针,还是先将字符逐个移动,然后遇到空格的时候需要一定的指针运算才能实现!
这里写图片描述

void my_replace(char * str)
{
    int k_num = 0;//定义空格数目
    int add_num = 0;
    int len = 0;//新字符串的长度
    int len2 = 0;
    char *m_str = str;
    assert(str != NULL);
    while (*m_str++)
    {
        if (*m_str == ' ')
            k_num++;
    }
    len2 = strlen(str) + 2 * k_num;
    len = strlen(str);
    int i = 0;
    m_str = str + len;
    while (*m_str != *str)
    {
        //如果遇到的不是空格
        if (*m_str != ' ')
                *(m_str + 2*k_num) = *m_str;
        else
        {
            *m_str = '%';
            *(m_str + 1) = '2';
            *(m_str + 2) = '0';
            for (i = 2; i >=0; i--)
                *(m_str + i + 2) = *(m_str + i);
        }
        m_str--;
    }
}

但是这种实现方式不太容易理解,代码量也是非常多!

更加高效的解法

我们可以先遍历一次字符串,这样就能统计出字符串中空格的总数,可以山此计算出替换之后的字符串的总长度。每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。我们还是以前面的字符串”We are happy.”为例,”We are happy.”这个字符串的长度是14(包括结尾符号’\0’),里面有两个空格,因此替换之后字符串的长度是18!
使用两个指针轻松解决此问题:
这里写图片描述
如图,p1指针指向\0,p2指针指向我们预期结果的字符串的末尾:

  • 逐个字符复制,p1向前走一步同时p2向前走一步就复制一个字符,直到p1遇到空格就停止
  • 当p1遇到空格的时候,p2连续做三次减法,同时分别赋值为%20,p1在向前走一步准备开始下一轮复制字符
  • 同样的道理循环开始下一轮复制,p1指针一直再往前走,只要p1走到字符串开头的位置便停止循环
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

void my_replace2(char * str)
{
    char *p1 = NULL;
    char *p2 = NULL;
    int len = 0;

    assert(str != NULL);

    len = strlen(str);
    p1 = str + len;
    p2 = str + len + 4;

    while (*p1 != *str)
    {
        if (*p1 != ' '){
            *p2 = *p1;
            p2--;
            p1--;
        }
        else
        {
            p1--;
            *(p2--) = '0';
            *(p2--) = '2';
            *(p2--) = '%';
        }   
    }
}

int main(void)
{
    char str[30] = "we are happy";
    //             "we%20are%20happy";
    printf("%s\n",str);
    my_replace2(str);
    printf("%s\n", str);
    system("pause");
}

这里写图片描述

考点

1、考查对字符串的编程能力。
2、考查分析时间效率的能力。我们要能清晰地分析出不同方法的时间效率各是多少。
3、考查对内存覆盖是否有高度的警惕。在分析得知字符串会变长之后,我们能够意识到潜在的问题,并主动和面试官沟通以寻找问题的解决方案。
4、考查思维能力。在从前到后替换的思路被面试官否定之后,我们能迅速想到从后往前替换的方法,这是解决此题的关键。

猜你喜欢

转载自blog.csdn.net/m0_38032942/article/details/81291895
今日推荐