剑指offer面试题5——替换空格 C语言

题目描述: 请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 输入: 每个输入件仅包含一组测试样例。 对于每组测试案例,输入一行代表要处理的字符串。 输出: 对应每个测试案例,出经过处理后的字符串。
样例输入: We Are Happy
样例输出: We%20Are%20Happy

文末有完整代码免费下载。

有这样一个实现思路,因为空格实际上占一个字符,而需要替换的%20占了 ‘%’ ‘2’ ‘0’ 3个字符。我们可以先获取字符串,然后获取字符串的长度,通过一个for循环对字符串从前到后进行扫描,当扫描到空格 ‘ ’ 的时候,就将空格替换成%20这三个字符,然后把剩下的所有字符都往后移动2位,继续扫描下一个空格,继续替换,继续将剩下的字符都往后移动…
这样做应该是没有问题的,但是在对每一个空格,都需要进行一次移位操作来保存后面的字符,否则后面的字符会被替换导致结果出错。这样一来计算量比较大。尤其是字符串较长,空格较多时,计算速度有差异明显。这里介绍两种时间复杂度O(n)的解法。

方法一:以空间换时间

构建一个辅助字符数组,在扫描原字符串的过程中,将相应的字符填在辅助字符的相应位置上。基本思路是从第一个字符扫描到最后一个字符,当扫描到空格 ‘ ’ 时,在辅助字符数组中填入 %20 ,并且标志位计数自加,用标志位来记录扫描到空格的个数。如果有一个空格,那么后面的其他字符在填到辅助字符数组中时,对应的位号要加2;如果有两个空格,那么对应的位号就加4,以此类推。我们来看看代码是怎么实现的:

char input[N];
char output[N]; 
int i,j;
int length;
int count = 0;

int main()
{
	while(gets(input) != NULL)
	{
		count = 0;
		length = strlen(input);
		for(i = 0;i <length;i++)
		{
			if(input[i] == ' ')
			{
				count++;
				output[(i+(count*2)) ] = '0';
				output[(i+(count*2))-1] = '2';
				output[(i+(count*2))-2] = '%';
			}
			else
			{
				output[i+(count*2)] = input[i];
			}
		}
		printf("%s\n", output);
	}
}

通过 while(gets(input) != NULL) 判断输入缓存区是否为空的方式,来实现连续输入。如果只需要输入一次字符串,替换一次,去掉while循环做相应修改即可。
这种方式不需要在每次扫描到空格时进行移位操作,节省了计算量,提高了计算速度,但是相应的牺牲了内存空间,需要一个辅助数组output[] 来实现功能。也就是以空间换时间,如果题目对计算速度有要求且内存空间没有限制的话,还是个不错的方法,逻辑简单易懂。

方法二 倒序替换

这个方法也是剑指offer上面给出的参考解法,前面有说到,直接替换之所以计算量大是因为要不断的对后面的数据进行移位,为什么要对后面的数据进行移位呢?因为如果没有不断移位的话,%20 这三个字符会替换掉原本字符数组中的相应字符导致输出结果错误。那么这种方法就是先遍历字符数组中的空格数量,然后根据空格的数量,将原数组从最后一位开始,直接一步到位移到他应该存在的位置。由于是从后往前开始逐位移动,可以一次将所有因为替换空格增加的字符位预留充足,所以并不会产生字符的覆盖。

char input[N];
int i,j;
int length;
int count = 0;

int main()
{
	while (gets(input) != NULL)
	{
		count = 0; //清零计数
		length = strlen(input); //字符串的实际长度是strlen(input)+1 最后一位结束符 \0 
		for(i = 0;i < length;i++)
		{
			if(input[i] == ' ')
			{
				count ++;  // 字符串中空格的数量 
			}
		}	
		for(j = (length-1);j >= 0;j--) //这里储存字符的位是length-1位  length位存放的是\0
		{
			if(input[j] == ' ')
			{
				input[(j+(count*2)) ] = '0';
				input[(j+(count*2))-1] = '2';
				input[(j+(count*2))-2] = '%';
				count--;
			}
			else
			{
				input[j+(count*2)] = input[j];
			}	
		} 
	printf("%s\n", input);
	}	
	return 0;
}

同时需要注意,使用while循环输入的时候,count = 0 清零操作要在while循环内,否则的话count无法清零会导致只有第一次运算结果是正确的,后面的运算结果一直出错。

剑指offer面试题5——替换空格 C语言

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值