剑指Offer(二):替换空格

题目

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

思路:

最简单的方法就是从头到尾遍历,但是时间复杂度为O(n^2)。

本文采用一种时间复杂度为O(n)的方法。

我们可以先遍历一次字符串,这样就可以统计出字符串空格的总数,并可以由此计算出替换之后的字符串的总长度。每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。以"We are happy"为例,"We are happy"这个字符串的长度为14(包括结尾符号"\n"),里面有两个空格,因此替换之后字符串的长度是18。

我们从字符串的尾部开始复制和替换。首先准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。接下来我们向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。碰到第一个空格之后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也要把P2向前移动3格。

将长度为1的空格替换为长度为3的“%20”,字符串的长度变长。 
如果允许我们开辟一个新的数组来存放替换空格后的字符串, 
那么这道题目就非常简单。设置两个指针分别指向新旧字符串首元素, 
遍历原字符串,如果碰到空格就在新字符串上填入“%20”, 
否则就复制元字符串上的内容。但是如果面试官要求 
在原先的字符串上操作,并且保证原字符串有足够长的空间来存放替换后的字符串,

那么我们就得另想方法。 
首先遍历原字符串,找出字符串的长度以及其中的空格数量, 
根据原字符串的长度和空格的数量我们可以求出最后新字符串的长度。 
设置两个指针point1和point2分别指向原字符串和新字符串的末尾位置。 
(这里取末尾开始遍历,而不是取起始开始遍历,是为了利用point1==point2这个判断条件) 
如果point1指向内容不为空格,那么将内容赋值给point2指向的位置, 
如果point1指向为空格,那么从point2开始赋值“02%” 
直到point1==point2时表明字符串中的所有空格都已经替换完毕。

è¿éåå¾çæè¿°

 

class Solution {
public:
	void replaceSpace(char *str,int length) {
		if(str == NULL || length <= 0){
            return;
        }
        /*original_length为字符串str的实际长度*/
        int original_length = 0;			//原始长度
        int number_blank = 0;				//空格数
        int i;
        while(str[i++] != '\0'){				//遍历字符串
            ++original_length;				//长度+1
            if(str[i] == ' '){
                ++number_blank;				//遇到空格+1
            }
        }
        /*new_length为把空格替换成'%20'之后的长度*/
        int new_length = original_length + 2 * number_blank;
        
        int index_original = original_length-1;	//原始字符串末尾索引值
        int index_new = new_length-1;				//计算长度后的字符串末尾索引值
        
        /*index_original指针开始向前移动,如果遇到空格,替换成'%20',否则进行复制操作*/
        while(index_original >= 0 && index_new > index_original){
            if(str[index_original] == ' '){
                str[index_new--] = '0';
                str[index_new--] = '2';
                str[index_new--] = '%';
            }
            else{
                str[index_new--] = str[index_original];
            }
            --index_original;
        }
	}
};

参考:https://blog.csdn.net/y912423222/article/details/87921420

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值