替换空格

目录

一、一个换多个

(1)原数组的长度大于替换后的长度。

(2)原数组的长度小于替换后的长度,需要额外创建一个数组保存替换后字符串。

二、多个换一个

三、拓展


字符串替换有两种情况,一种是把一个空格换成多个字符,另一种是把多个空格换成一个空格。


一、一个换多个

题目:请实现一个函数,把字符中的每个空格替换成"%20".

(1)原数组的长度大于替换后的长度。

思路:额外定义一个数组 ,如果是字符,直接拷贝,如果是空格,就把'%','2','0'分别复制过去,最后用拷贝函数将数组里的字符串拷贝到元素组,最后释放这个数组,时间复杂度为O(n),空间复杂度为O(n)。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
char* StringReplace(char * arr)
{
	int len = strlen(arr);
	int newlen = 0;
	int count = 0;
	for(int i=0;i<len;i++)
	{
		if(arr[i] == ' ')
		{
			count += 1;
		}
	}
	newlen = 2*count +strlen(arr);
	char *des = (char *) malloc (sizeof(char) * (newlen+1));
	//char * res = des;
	for(int i = 0,j =0 ;i < len;i++,j++)
	{
		if(arr[i] == ' ')
		{
			des[j] = '%';
			des[++j] = '2';
			des[++j] = '0';
		}
		else
		{
			des[j] = arr[i];
		}
	}
	des[newlen] = '\0';
	strcpy(arr,des);
	free(des);
	return arr;
}

int main()
{
	char arr[100] = "a b c";//len = 5 加'\0'为6
	StringReplace(arr);
	printf("%s\n",arr);
	return 0;
}

 

上面的做法空间复杂度可以降低,直接在原数组里操作,以防覆盖数据,所以将字符串数组从后往前拷贝,碰到空格,就把'0','2','%'赋值进去,如果是字符就直接赋值进去。

优化代码:

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

char* Stringreplace(char *str,int len)
{
	assert(str != NULL && len > 0);
	int oldtlen = strlen(str);//旧的字符串长度
	int newlen = 0;//新的字符串长度
	int count = 0;//统计空格个数
	for(int  i = 0;i<oldlen;i++)
	{
		if(str[i]  == ' ')
		{
			count ++;
		}
	}
	newlen = count*2+oldlen;
	if(len <newlen || newlen == oldlen)
	{
		return str;
	}
	for(int i = oldlen-1, j = newlen -1;i>= 0;i--,j--)
	{
		if(str[i] != ' ' )
		{
			str[j] = str[i];
		}
		else
		{
			str[j] = '0';
			str[--j] = '2';
			str[--j] = '%';
		}
	}
	return str;
}

int main()
{
	char str[20] = "a b c";
	int len = 20;
	printf("%s\n",str);
	char * des = Stringreplace(str);
	printf("%s\n",des);
}

(2)原数组的长度小于替换后的长度,需要额外创建一个数组保存替换后字符串。

思路和上面的同理。时间复杂度为O(n),空间复杂度为O(n)。

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

char* Stringreplace(char *str)
{
	assert(str != NULL);
	int len = strlen(str);//旧的字符串长度
	int newlen = 0;//新的内存大小
	int count = 0;//统计空格个数
	for(int  i = 0;i<len;i++)
	{
		if(str[i]  == ' ')
		{
			count ++;
		}
	}
	newlen = count*2+len;
	printf("%d\n",newlen);
	char * des = (char *) malloc ( sizeof(char) * (newlen+1));
	des[newlen] = '\0';
	for(int i = len-1, j = newlen -1;i>= 0;i--,j--)
	{
		if(str[i] != ' ' )
		{
			des[j] = str[i];
		}
		else
		{
			des[j] = '0';
			des[--j] = '2';
			des[--j] = '%';
		}
	}
	return des;
}

int main()
{
	char str[20] = "a b c";
	printf("%s\n",str);
	char * des = Stringreplace(str);
	printf("%s\n",des);
	free(des);
}

 


 

二、多个换一个

题目:请实现一个函数,把字符串中的多个空格变成一个空格。

思路:在原数组里操作,因为是多个空格变成一个空格,所以新的数组长度一定等于或者小于元数组的长度。为防止覆盖数组,从左往右开始拷贝。定义两个变量,i和j,碰到两个空格相连,i++,j不动,其他情况数组i下标的值赋给j下标的值。

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

char* Stringreplace(char* str)
{
	assert(str != NULL);
	int len = strlen(str);
	int i = 0,j = 0;
	for(;i<len;i++)
	{
		if( !(str[i] == ' ' && str[i+1] == ' '))
		{
			str[j] = str[i]; 
			j++;
		}
	}
	str[j] = '\0';
	return str;
}
int main()
{
	char str[100] = "a  b  c    d  ";
	Stringreplace(str);
	printf("%s\n",str);
	return 0;
}

 


 

三、拓展

题目:将字符串里的"*"都放到前面,将字符按顺序输出。

思路:在原数组里操作,所以要从后往前拷贝。先把*的个数统计出来,然后从后往前拷贝,碰到*不拷贝,继续往下遍历,直到原数组的字符已经全部拷贝,将前面的全部拷贝成*。

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

char* Stringreplace(char * str)
{
	int count = 0;
	int len = strlen(str);
	int j  = len-1;
	for(int i = 0;i<len;i++)
	{
		if(str[i] == '*')
		{
			count ++;
		}
	}

	for(int i = len-1;i>=0;i--)
	{
		if(str[i] !='*')
		{
			str[j] = str[i];
			j--;
		}
	}
	for(j = count-1;j>= 0;j--)
	{
		str[j] = '*';
	}
	return str;
}
int main()
{
	char str[100] = "a*b*c";
	printf("%s\n",str);
	Stringreplace(str);
	printf("%s\n",str);
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值