题目:请实现一个函数,将一个字符串中的空格替换成“%20”。
例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
1.暴力替换
<1>从后往前遍历字符串
<2>每找到一个空格,需要将’ ‘后面的字符串依次后移两位,预留出%20的空间
#include <iostream>
using namespace std;
class Solution
{
public:
void replaceSpace(char *str, int length)
{
int len = length;//用来记录扩容后的数组长度
//从后往前遍历
for(int i = length - 1; i >= 0; i--)
{
if(str[i] == ' ')
{
len += 2;
for (int j = len - 1; j > i + 2; j--)
{
str[j] = str[j - 2];
}
str[j--] = '0';
str[j--] = '2';
str[j--] = '%';
}
}
str[len] = '\0';
}
};
2.优化
上述代码主要消耗的时间在于,如果有多个空格,那么每遇到一个空格就进行移位,其实前面的移位是没有必要的,如果在遇到空格,那么之前的移位全是无用功。
因此,我们可以考虑先遍历一遍字符串,计数空格的数目,我们知道了空格的数目,其实就是知道了替换后字符串的长度,那么只需要进行一次替换就可以了
因此,我们的工作变为
<1>遍历一遍字符串,统计字符出现的数目,计算替换后的字符串长度
<2>再遍历一遍字符串,完成替换
#include <cstdio>
#include <cstring>
void ReplaceBlank(char str[], int length)
{
if(str == nullptr && length <= 0)
return;
//originalLength为字符串str的实际长度
int originalLength = 0;
int numberOfBlank = 0;
int i = 0;
while(str[i] != '\0')
{
++ originalLength;
if(str[i] == ' ')
++ numberOfBlank;
++i;
}
//newlength为把空格替换成'%20'之后的长度
int newLength = originalLength + numberOfBlank * 2;
if(newLength > length)
return;
int indexOfOriginal = originalLength;
int indexOfNew = newlength;
while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
{
if(str[indexOfOriginal] == ' ')
{
str[indexOfNew --] = '0';
str[indexOfNew --] = '2';
str[indexOfNew --] = '%';
}
else
{
str[indexOfNew --] = str[indexOfOriginal];
}
--indexOfOriginal;
}
}