题目:要求写一个函数,将字符串中的空格替换为%20,样例:“i like flower”转换成“i%20like%20flower”,要求时间复杂度为O(n)。
在网络编程中,如果URL参数中有特殊字符,如空格,“#”等,可能导致服务器端无法获得正确的参数值,我们需要将这些特殊符号转换为服务器可以识别的字符。转换规则为:“%”后面跟上ASCII码的两位十六进制的表示,比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换为“%20”,同理可得“#”被替换为“%23”。
很直观的,我们首先会想到的做法就是从头开始扫描字符串,每次遇到空格就进行替换,然后把空格后面所有字符向后移动两个字节,这样才不会使后面的字符被覆盖,移动过程可以形象地用下图表示。
假设字符串长度为n,对每个空格字符,需要移动后面的O(n)个字符,因此对于含有O(n)个空格字符的字符串而言,总的时间效率为,但是这样的时间复杂度太大了。我们可以换一种思路,先遍历一次字符串,统计空格总数并计算替换后字符串长度,最后其长度为原来长度加上2乘以空格数目,然后从字符串后面开始复制与替换。
如上图所示,我们准备两个指针p1,p2,让p1指向原始字符串的末尾,而p2指向替换后的字符串的末尾,向前移动p1,把它指向的字符复制到p2指向的位置,直到碰到空格为止。当遇到空格之后,p1先前移动一格,p2向前移动3格且插入“%20”,然后再接着向前复制,直到p1与p2指向同一位置,表明所有空格都已替换完毕。此方法中所有字符只移动一次,因此时间复杂度为O(n),比第一种思路要快,下面是我的完整代码,如有错误,还请指出。
#include <stdio.h>
#include <stdlib.h>
void ReplaceBlank(char string[], int len)
{
int i = 0;
int orglen = 0;
int numblank = 0;
int newlen = 0;
if (string == NULL && len <= 0)
return;
while (string[i]!='\0')
{
++orglen;
if (string[i] == ' ')
{
++numblank;
}
++i;
}
newlen = orglen + numblank * 2;
if (newlen > len)
return;
int indexoforg = orglen;
int indexofnew = newlen;
while (indexoforg >= 0 && indexofnew > indexoforg)
{
if (string[indexoforg] == ' ')
{
string[indexofnew--] = '0';
string[indexofnew--] = '2';
string[indexofnew--] = '%';
}
else
{
string[indexofnew--] = string[indexoforg];
}
--indexoforg;
}
}
int main()
{
char arr[20] = "i like flower";
int len = sizeof(arr) / sizeof(arr[0]);
ReplaceBlank(arr, len);
printf("%s\n", arr);
system("pause");
return 0;
}