字符串空格替换或删除

1.将一个字符串里面的空格替换成%20,不考虑字符数组大小溢出,不得使用库函数

2.将一个字符串里面的一个或多个空格替换成一个空格


这两道题都是关于字符串替换,不同的是第一道题是将一个空格替换为3个字符%20,当然这里任意3个字符都可以,而且只要保证数组大小足够大,一个空格替换成多个也无所谓,本质上是将一个字符替换成多个字符从而增加原字符的长度。

而第二个的话则是将多个字符(只不过是相同的)替换成一个字符,从而减小原字符串的长度。


对于第一道题,可以这么考虑,先遍历字符串求取原来的字符串长度oldLen和空格个数blankNum,由题可知每多一个空格字符串长度就增加(3-1)个即新字符串的长度newLen=oldLen+2*blankNum,最后将原来的字符串自后向前拷贝到新的空间,如图所示,以hi usa为例。

代码如下:

void replaceBlank(char *str)
{
	assert(str);
	int oldLen = 0;
	int newLen = 0;
	int blankNum = 0;
	//两种求oldLen的方法
	//char *p = str;
	//while (*p != '\0') {
	//	if (*p == ' ')
	//		blankNum++;
	//	p++;
	//}
	//oldLen = p - str;
	while (str[oldLen] != '\0') {
		if (str[oldLen] == ' ')
			blankNum++;
		oldLen++;
	}
	newLen = oldLen + 2 * blankNum;
	while (newLen >= 0){
		if (str[oldLen] == ' ') {
			str[newLen--] = '0';
			str[newLen--] = '2';
			str[newLen--] = '%';
			oldLen--;
		}
		else
			str[newLen--] = str[oldLen--];
	}
}

对于第二题,我自己是这么考虑的,还是遍历整个字符串,在遍历的过程中遇到非空格指针string++,遇到第一个空格的时候不管还是string++, 直到遇到第二个空格记下第二个空格的位置p=string,然后string指针继续走看是否还有连续的空格直到遇到非空格,此时string指针指向非空格的位置,然后将string及以后字符串拷贝到p以后位置,如图所示 (即字符串is a  man\0整体向前移动一位)


那么为什么还要设置一个q指针来保存遇到第二个空格时候string的位置呢?

那是因为在拷贝的时候*p++=*string++指针p和string位置都变化了,需要有个q指针保存之前的位置从而string好定位,来继续执行循环。(移动完字符串如下图)



代码如下

void deblank(char *string)
{
	int flag = 0;
	while (*string != '\0') {
		if (*string != ' ') {
			string++;
			flag = 0;
		}
		else {
			if (flag == 0) {
				string++;
				flag = 1;		
			}
			else if (flag == 1) {
				char *p = string;//指针p q记下当前指针的位置
				char *q = string;
				while (*string == ' ')
					string++;

				while (*string != '\0') {
					*p++ = *string++;
				}
				*p = '\0';
				//两种拷贝字符串的方法
				//while (*p++ = *string++)
				//	;

				string = q;
			}
		}
	}
}

C和指针书上给出另一种实现方式,设置两个指针src和dst,让src先走,执行src向dst的拷贝,遇到非空格直接拷贝,遇到空格看前面一个是否是空格,如果不是就拷贝否则就不操作。

代码如下

int is_white(int ch) 
{ 
	return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\n' || ch == '\r'; 
}

void deblank(char *string)
{
	int ch = ' ';
	char *src = string;
	char *dst = string++;
	while ((ch = *src++) != '\0') {
		if (is_white(ch)) {
			if (src == string || !is_white(*(dst - 1))) {
				*dst++ = ' ';
			}
		}
		else {
			*dst++ = ch;
		}
	}
	*dst = '\0';
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值