一、题目
请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.”。
二、解法
思路:如果在原来的字符串上进行替换,就有可能覆盖修改该字符串后面的内存。如果创建新的字符串并在新的字符串上进行替换,那么可以自己分配足够多的内存。因此有两种解决方案,一种是在原字符串上进行替换,并且保证输入的字符串后面有足够多的空余内存,另一种是创建新的字符串。
2.1 方法一
如何执行替换操作,最直观的做法是从头到尾扫描字符串,每次碰到空格字符进行替换,由于把一个字符替换为3个字符,我们必须把空格后面的所有字符都后移两个字节,否则就有两个字符被覆盖了。
分析:假设字符串长度为n, 对每个空格字符,需要移动后面O(n)个字符,因此对于含有O(n)个空格字符串而言,总的时间效率为O(n2)
2.2 方法二
我们可以先遍历一次字符串,这样就能统计出字符串中空格的总数,并可以由此计算出替换之后的字符串的总长度。每替换一个空格,长度加2,我们从字符串后面开始复制和替换。首先准备两个指针:p1和p2。p1指向原始字符串的末尾,而p2指向替换之后的字符串的末尾,接下来我们向前移动指针p1, 逐个把它指向的字符复制到p2指向的位置,知道碰到第一个空格为止。由于所有的字符都只复制(移动)一次,因此这个算法的时间效率为O(n),比第一种方法快。
class Solution {
public:
void replaceSpace(char *str,int length) {
//length为字符数组str的总容量
if(str==nullptr || length<0)
return;
int originalLength = 0;
int numberOfBlank = 0;
int i = 0;
while(str[i]!='\0')
{
++originalLength;
if(str[i] == ' ')
++numberOfBlank;
++i;
}
int newLength = originalLength + 2* numberOfBlank;
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;
}
}
};