题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.”。
解析:
方法一:直观做法就是从头到尾扫描字符串,每次碰到空格进行替换。
假设字符串长度为 n ,对每个空字符需要移动 O(n) 个字符,对含有O(n) 个空格的字符串,时间复杂度为 O( n2)
(b) 替换第一个空格,移动浅灰色部分
(c) 替换第二个空格,移动浅灰色一次,移动深灰色两次
方法二: 遍历一遍字符串,统计空格总数,计算替换后的总长度。从字符串后面开始复制和替换(两个指针指向原尾部,及替换后的尾)。
每个字符只移动(复制)一次,时间复杂度 O(n)
举一反三:
在合并两个数组(包括字符串)时,如果从前往后复制每个数字则需要重复移动数字多次,那么可以考虑从后往前复制,这样就能减少移动次数,从而提高效率。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
void replaceSpace(char *str, int length) // * length 为字符数组str的总容量,大于或等于字符串str的实际长度
{
if (str == nullptr || length <= 0) //判断是否为空
return;
int BeforeLength = 0; // 字符串实际长度
int NullLength = 0; //空格个数
int i = 0;
while (str[i] != '\0') //统计空格
{
++BeforeLength;
if (str[i] == ' ')
++NullLength;
++i;
}
int AfterLength = BeforeLength + NullLength * 2;
if (AfterLength>length)
return;
int indexOfBefore = BeforeLength;
int indexOfAfter = AfterLength;
while ((indexOfBefore >= 0) && (indexOfAfter>indexOfBefore))
{
if (str[indexOfBefore] == ' ')
{
str[indexOfAfter--] = '0';
str[indexOfAfter--] = '2';
str[indexOfAfter--] = '%';
}
else
str[indexOfAfter--] = str[indexOfBefore];
--indexOfBefore;
}
}
int main()
{
const int length = 100;
char str[length] = "hello world";
replaceSpace(str, length);
cout << str << endl;
system("pause");
return 0;
}
空格 ASCII码 32 十六进制 0x20 URL中被替换成“ %20 “
# ASCII码 35 十六进制 0x23 URL中被替换成” %20 “