背景:网络编程中,如果说URL参数中含有特殊字符,就拿空格说,可能导致服务器端无法获得正确的的参数值,这个时候就需替换。
1.空格,替换成%20
2.#被替换成%23,等
下边看看,以字符串中空格被替换成%20的场景:例子为 替换 we are happy 中的空格;
总体思想:
1.遍历找空格。
2.移动字符位置。
3.替换空格。
第一种:时间复杂度O(n^2)
如果,从头开始遍历,遇到空格后,需要将空格后的所有字符串后移动两个位置,如果在遇到空格,空格后的字符串又得在移动,看图:
图中意思到就行,主要说明,字符串happy被移动了两次,假设,字符串长度为N,对于每一个空格字符来说,需要移动以后O(n)个字符
对于含有O(n)个空格字符的字符串来说,时间效率就是O(n^2), 这种效率是不可以的。
当然:对于那些重新申请空间来装增长后的字符串的方法,时间上是提高了效率,但同时也消耗了空间,总体来说,不是最好的。
来看一种相对比较好的:
第二种:时间复杂度O(n)
方法步骤:
1.遍历字符串,统计空格个数,统计字符创总长;
2.每个空格加两个字符长度,计算所有空格替换为响应字符后的总长度;
3.从字符串的后边往前替换,
上图,看图理解:
从后往前替换,p2指向增长后的字符串,p1指向原来字符串,p1和p2同时往前移动,当p1遇到空格时,p2停下来,
在p1的位置插入替换的字符串最后一个字符,例如替换的字符串是“%20“,那么就在p1位置插入0,p1继续前移,p2不动,
相同的方法插入% 2 等字符,当p1指向%前一个字符,p2 开始动,当p1 == p2结束 over
上代码:
//length 为字符数组string的总容量
void ReplaceBlank(char string[], int length)
{
//如果字符串为空,返回
if(string == NULL && length <= 0)
return;
int originalLength = 0; //originalLength 为字符串string的实际长度
int numberOfBlank = 0; //空格数
int i = 0;
while(string[i] != '\0')
{
++ originalLength; //字符串原长统计
if(string[i] == ' ')
++ numberOfBlank; //空格数统计
++ i;
}
//newLength 为把空格替换成'%20'之后的长度
int newLength = originalLength + numberOfBlank * 2;
if(newLength > length)
return;
int indexOfOriginal = originalLength; //相当于图中的p1
int indexOfNew = newLength; //相当于图中的p2
while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
{
if(string[indexOfOriginal] == ' ')
{
string[indexOfNew --] = '0';
string[indexOfNew --] = '2';
string[indexOfNew --] = '%';
}
else
{
string[indexOfNew --] = string[indexOfOriginal];
}
-- indexOfOriginal;
}
}
赐教!