请实现⼀个函数,将⼀个字符串中的每个空格替换成“%20”。例如,当字符串为WeAreHap。。。
⼀、题⽬描述
请实现⼀个函数,将⼀个中的空格替换成“%20”。例如,当为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
⼆、解题思路
1)简单暴⼒解法,我们可以很容易的想到,碰到⼀个空格,就加⼊%20,于是可以从头到尾遍历字符串,碰到空格,⾸先将后⾯的所有字符串往后移动2个字符,这样才能空出3个字符位⼦插⼊字符“%20”,对于⼀个长度为n的字符串,对每个空格,需要移动后⾯O(n)个字符,因此包含n个空格的字符串,总的时间复杂度为O(n*n)。这个代码就不写了...
2)我们仔细的思考,难道我们真的只能0(n*n)的复杂度吗?不,我们可以更快!
我们从后往前开始替换,⾸先遍历⼀遍字符串,统计出空格的个数,并由此能够计算出替换之后的字符串的长度。
举个例⼦:
每替换⼀个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数⽬。以"We are happy"为例,"We are happy"这个字符串的长度为14(包括结尾符号"\n"),⾥⾯有两个空格,因此替换之后字符串的长度是18。
接着再次从后往前遍历字符串,同时设置两个指针P1和P2,P1指向原始字符串末尾,P2指向替换之后的字符串末尾。我们向前移动P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第⼀个空格为⽌。然后把P1向前移动⼀格,在P2之前插⼊字符串“%20”,同时P2向前移动3格。重复此过程,直到所有的空格都已替换完。这样只需要扫描⼀遍,时间复杂度为O(n)。
移动⽰意图如下:
#include <iostream>
#include <iterator>
using namespace std;
void replaceSpace(char* str,int length) {
char* ots = NULL;
if (str == NULL && length <= 0) {
return;
}
/*original_length为字符串str的实际长度*/
int original_length = 0;  //原始长度
int number_blank = 0;    //空格数
int i = 0;
while (str[i++] != '\0') {    //遍历字符串
++original_length;    //长度+1
if (str[i] == ' ') {
++number_blank;    //遇到空格+1
}
}
/*new_length为把空格替换成'%20'之后的长度*/
int new_length = original_length + 2 * number_blank;
ots = (char*)malloc(new_length * sizeof(char));
memset(ots, 0, strlen(ots));
if (ots == NULL) return;
memcpy(ots, str, strlen(str));
int index_original = original_length; //原始字符串末尾索引值
int index_new = new_length;    //计算长度后的字符串末尾索引值
/*index_original指针开始向前移动,如果遇到空格,替换成'%20',否则进⾏复制操作*/
字符串长度可以为1吗while (index_original >= 0 && index_new > index_original) {
if (ots[index_original] == ' ') {
ots[index_new--] = '0';
ots[index_new--] = '2';
ots[index_new--] = '%';
}
else {
ots[index_new--] = ots[index_original];
}
--index_original;
}
cout << ots << endl;
};
int main()
{
const char* tmp = "wu han tai re li";
char* p = const_cast<char*>(tmp);
replaceSpace(p, strlen(p));
return 0;
}
 事实上,很多⽹络上的代码你是绝对编译不通过的,原因很简单,str被重新计算了,然后⽤新的⼤⼩去索引,不崩溃才怪。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。