【剑指offer】面试题4替换空格


题目:替换字符串中的空格为“%20”。
说明:在浏览器的地址栏中输入某个网址,在解析过程中会看到类似“%20”的字样,这应该就是网络编程涉及的内容。。。


这个题目非常简单,只是通过一步遍历,然后将一个字符串数组赋给另外一个数组的过程中,遇到空格,插入‘%20’即可。

但是:考虑问题还是不全面,我们应该问清楚是在原数组的基础上插入,还是创建一个新的数组然后再赋值。不能太想当然了,我的解题思路是按照创建一个新的数组,为了避免过度浪费,就用动态创建。当不够用的时候再分配一倍的数组空间。这时利用multi变量来表示倍数。


代码如下:

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

char *replace_space(char arr[],int length);

int main(void)
{
    char buf[] = "a  !   ";

    printf("size of buf :%d,%d\n",sizeof(buf)/sizeof(char),sizeof(char));
    char *tempbuf = replace_space(buf,sizeof(buf)/sizeof(char));
    printf("%s",tempbuf);

    return 0;
}


char *replace_space(char arr[],int length)
{
    int multi = 2;
 //   int length = sizeof(arr)/sizeof(char);    //这一行代码是不正确的,sizeof(arr)只是指针占据的空间,不是数组
    char *temparr = (char *)malloc(multi*length *sizeof(char));
    char *buf = temparr;

    while(*arr){
        if((buf-temparr)+3 > multi * length){   //动态分配新的数组大小
            int len = buf - temparr;
            temparr = (char *)realloc(temparr,(++multi) * length * sizeof(char));
            buf = temparr + len;    //不仅数组起始指针要保留,遍历过程的指针也要保留
        }

        if(*arr == ' '){
            *buf++ = '%';
            *buf++ = '2';
            *buf++ = '0';
            arr++;
        }
        else
            *buf++ = *arr++;
    }
    *buf = '\0';    //必须加上,以对字符串设置结束标志!
    return temparr;
}

说明:

(1)关于用指针和数组的差别,剑指offer举出了这样一个例子:

int get_size(int data[])
{
    return sizeof(data);
}
int main(void)
{
    int data1[] = {1,2,3,4,5};
    int size1 = sizeof(data1);
    
    int *data2 = data1;
    int size2 = sizeof(data2);
    
    int size3 = get_size(data1);
    printf("%d %d %d",size1,size2,size3);
}

输出结果为“20,4,4”。求data2的时候容易看出,这里的data2只是一个指针,因此sizeof()后只是一个指针占的空间大小。在32位系统上,对任意的指针进行sizeof均为四个字节。但是将数组传递给函数时,其实传递的也是指针!对其进行求取,也是4。

(2)通过跟作者的代码比较,体现了自己的很多不足:

使用变量名时,尽量使用有意义的名字;无论指针还是数组名,由于都是地址,在使用之前一定要判空(为了维护代码的健壮性)。

作者代码:

void replaceBlank(char string[],int length)
{
    if(string == NULL && length <=0)
        return;
    /*originalLength为字符串string的实际长度*/
    int originalLength = 0; //统计字符串总数,以及空格的总数
    int numberOfBlank = 0;
    int i = 0;
    
    while(string[i]!='\n'){ //能否简化为string[i]?
        ++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;
    }
}

评注:作者代码考虑的全面,考虑了程序的健壮性,并且当要插入数据的时候,可以从数组后向前遍历进行复制,技巧很好。




你可能感兴趣的:(算法,剑指offer)