实现一个函数,将一个字符串中的所有空格替换为"%20",例如输入字符串"How beautiful you are!",输出结果应为"How%20beautiful%20you%20are!"。


首先,如果另开辟一块空间并且足够将全部空格都替换成"%20",然后一个单词一个单词的拷贝过去,当遇到空格时就放进去"%20",这种低效率的方法肯定是可行的,但很显然不仅效率不高还浪费存储空间,因此,要节省空间就要在原来字符串的空间上做改变,前提条件是原字符串所在的空间足以存放将空格全部改为"%20"之后的字符串,因为毕竟"%20"的大小要比一个空格要大;

然后就可以想到遍历字符串,当遇到空格时就将剩下的字符都后移strlen("%20")个长度,然后将"%20"放进去,再依次往后遍历;这样的方法虽然节省空间,但是效率并不高,因为每遇到一个空格后面的字符就要往后移,因此最后一个字符所移动的次数就是字符串中的空格数,也就是一个字符可能要移动多次才能到达它所应该待的最后的位置;

因此,可以反过来换一种思路,就是计算出最后一个字符应该待的位置,一次性就把它给移过去,也就是从后往前遍历,当遇到空格的时候就将字符串"%20"放进去,直到遍历到原字符串首部,这样就将空格都替换好了,而且每个字符也都只移动了一次就到了自己应该待的位置;

代码实现如下:

#include<iostream>#include<stdio.h>#include<string.h>#include<assert.h>usingnamespacestd;voidReplaceSpace(char*&dst,constchar*src){assert(dst&&src);//判断参数的有效性char*tmp=dst;size_ts_count=0;while(*tmp!='\0')//计算字符串中空格的个数{if(*(tmp++)=='')++s_count;}size_tdst_len=strlen(dst);//要被替换的字符串长度size_tsrc_len=strlen(src);//要替换的字符串长度char*tail=dst+dst_len;//被替换的字符串的尾部最后一个字符'\0'char*right_place=tail+s_count*(src_len-1);//替换后最后一个字符应该待着的位置while(tail>=dst){if(*tail!=''){*right_place=*tail;//当字符不为空格时挨个移到替换后的位置}else{right_place-=(src_len-1);//要替换的字符串开始拷贝的起始位置strncpy(right_place,src,src_len);}--tail;--right_place;}}intmain(){char*str=newchar[1024];cout<<"pleaseinputstring:";gets(str);ReplaceSpace(str,"20%");cout<<"Thestringafterreplace:"<<str<<endl;delete[]str;return0;}


运行程序:


其实我想过如果将字符串的存储空间设定为动态增容的,这样既不会有空间不够用的情况也不会有一次性把空间给大了浪费的问题,但是后来一开始试着实现就发现这样根本不行,因为字符串是手动输入的,当输入的时候很有可能就已经超过了开辟的最大存储空间的范围,更别说后面的检查容量啊增容啊什么的。



《完》