【剑指offer】面试题5:字符串-替换空格

本文介绍了一个面试题,要求将字符串中的每个空格替换为%20。作者分享了自己在解决问题过程中遇到的陷阱,如未区分空格字符和单引号,以及错误地计算字符串长度。通过讨论这些问题,作者强调了在处理字符串时需要注意的细节,并提供了大佬的参考答案。
摘要由CSDN通过智能技术生成

1. 题目要求

请实现一个函数,把字符串中每一个空格替换成%20。

2. 题目分析

看似很简单的题目,但是却暗藏了坑。本来空格只占一个位置,但是替换后变成了%20,所以字符串的内存是可变的嘛?覆盖会造成的问题

3. 自己先想一想

我最开始以为这道题目很简单,但是在写代码的时候,在思考的时候,才会有很多看书的时候会忽略的“坑”,而我算运气好还是差呢?几乎把能踩的坑都踩了一遍吧。磕磕绊绊,写出了如下的代码。(里面多余的打印信息只是为了看运行过程而已,没有啥用)

#include <stdio.h>
#include <stdlib.h>

void replaceSpace(char str[],int length)
{
    printf("length:%d\n",length);
    int i,count=0,end;
    for(i=0;i<length;i++)
    {
        //if(*(str+i)==" ")
        if(*(str+i)==' ')
        {
            count++;
        }
    }
    printf("%d\n",count);
    end = length + count * 2;
    printf("end:%d\n",end);
    char *p1,*p2;
    p1= (str+length);
    p2= (str+end);
    printf("%x\n",p1);
    printf("%x\n",p2);
    while(p1>str)
    {
        if( *p1 != ' ')
        {
            *p2=*p1;
            p1--;
            p2--;

        }else if(*p1 == ' ')
        {
            *p2='2';
            *(p2-1)='0';
            *(p2-2)='%';
            p1--;
            p2=p2-3;
        }

    }
    printf("%s\n",p2);

}
int main()
{
    //输入字符串
    char str[]="we are happy!";
    int len;
    len = sizeof(str)+1;
    printf("len : %d; sizeof(str) : %d\n",len,sizeof(str));
    replaceSpace(str,len);

    return 0;

}

最后的运行结果如下图:

3.1 踩过的“坑”

1)在判断的时候没有区分" " 和' ' 

//if(*(str+i)==" ")
  if(*(str+i)==' ')

这个问题还挺严重的,因为这直接导致了count的值,单纯的' ' 是没有\0的,所以count一直是0

2)长度的计算

sizeof不会加上最后的\0的,所以在长度上要加1;

在循环判断的时候,也要分外注意呢!!这些条件是最容易错的地方了

 //千万不要写成*p2="%20"!!!,要时刻记得\0的存在

最好动手画一画,关于加加减减的值一定要很注意呢!

 while(p1>str)
    {
        if( *p1 != ' ')
        {
            *p2=*p1;
            p1--;
            p2--;

        }else if(*p1 == ' ')
        {
            *p2='0';    //千万不要写成*p2="%20"!!!,要时刻记得\0的存在
            *(p2-1)='2';
            *(p2-2)='%';
            p1--;
            p2=p2-3;
        }

    }

越看越觉得自己应该只是菜鸟阶段吧,只能磕磕绊绊的把功能实现完成,还是看一看大佬的参考代码吧 

4. 大佬的参考答案

#include <stdio.h>
#define NULL ((void *)0)
//length是string数组的总容量
//void replaceBlank(char string[],int length)
void replaceBlank(char string[])
{
    //if(string == NULL || length <= 0)
        //return;
    int originalLength=0;
    int numberOfBlank=0;
    int i = 0;
    while(string[i]!='\0')
    {
        ++originalLength;
        if(string[i]=' ')
            ++numberOfBlank;
        ++i;
    }
    int newLength=originalLength+numberOfBlank*2;
   // if(newLength>length)
       // return;
    int indexOfOriginal = originalLength;
    int indexOfNew = newLength;
    while(indexOfOriginal>=0&&indexOfNew > indexOfOriginal)
    {
         if(string[indexOfOriginal == ' '])
        {
            string[indexOfNew--]='0';
            string[indexOfNew--]='2';
            string[indexOfNew--]='%';
        }else{
            string[indexOfNew--]=string[indexOfOriginal];
        }
        --indexOfOriginal;
    }

}

int main()
{
    //输入字符串
    char str[]="we are happy!";
    //int len=50;
    //len = sizeof(str)+1;
    //printf("len : %d; sizeof(str) : %d\n",len,sizeof(str));

    replaceBlank(str);

    return 0;

}

不知道为什么,能编译但无法运行。。。真是奇怪呢?

但大佬的代码有一种高逼格的感觉,是因为他的名字取得比较高级吧。还是有很多值得学习的地方,比如对一些特殊字符串的处理

比如:对空字符串;对连续的空格字符串;对没有字符串的数组;

 

20190708的更新

class Solution {
public:
	void replaceSpace(char *str,int length) {
        if(*str == NULL || length == 0)
            return;
        
        int count = 0;
        int i;
        for(i=0;i<length;i++)
        {
            if(*(str+i)==' ')
                count++;
        }
        //两个指针,一个指向原本的末尾一个指向替换后的末尾
        char *p1;
        char *p2;
        p1 = str+length;
        p2 = p1+count*2;
        
        //进行字符串拷贝
        while(p1 != p2)
        {
            if(*p1==' ')
            {
                *p2 = '0';
                *(p2-1) = '2';
                *(p2-2) = '%';
                p1--;
                p2 = p2-3;
            }
            else
            {
                *p2 = *p1;
                p2--;
                p1--;
            }
        }
	}
};

不要相当然的偷懒

比如p2 = p2 -3 写成p2 -3 .....

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值