替换空格
题目描述:
实现一个函数,将字符串中的每个空格替换成"%20"。例如:输入“We are happy.”,则输出"We%20are%20happy."。
分析:
我们这题就先假设所给的字符串长度够长,足以用来将全部空格替换成"%20",不然的话替换的时候就会覆盖原有的字符串喽。
以string = “We are happy.”
为例子,如图所示:原始string空格处插入"%20"
之后就变成了新的字符串newString。
在操作的时候我们先计算出原始string的长度为14(包括结尾处的'\0'
字符),每替换一个空格总的长度就会增加2,那新的字符串newString的长度就为14+2*空格数=14+2*2=18
。
我们在替换的时候就倒着来进行替换,若没碰见空格' '
,就正常向后移动即可;若碰到空格,则分别插入'0'
,'2'
,'%'
即可,直到碰见第一个字符为止。
这样对于每个字符只需要复制(移动)一次即可,因此时间效率为O(n)。
pass:若从前往后进行替换,假设字符串长度为n,对于每个空格需要移动后面O(n)个字符,因此对于含有O(n)个空格的字符串来说,总的时间效率为O(n^2),显然时间复杂度大。
备注:O表明某个算法的耗时/耗空间与数据增长量之间的关系。
考察队内存覆盖是否有警惕性 ,思维能力,是否能找到最优处理方式。。
伪代码:
void replaceBlank(char string[], int length)
{
//length是一个长度足够大的值;
//先特殊处理
数组指针为空指针或者这个长度小于等于0了,直接返回;
//处理
遍历这个数组:
若碰见空格:记录空格的个数;
若碰见字符:记录字符的个数;
计算数组内空格替换后的数组长度值得到newlen;
若这个值大于最初的length,就表明之后不能正常输出替换后的数组;
//开始替换
若newlen不为0:
若碰见空格:
在这个位置插入字符串%20;
否则:
将原始的字符进行复制;
--newlen;
}
代码:
#include<iostream>
#include<string>
using namespace std;
void replaceBlank(char string[], int length)
{
//假定这个string的长度满足将空格替换后的长度
//注意这里的length为string的总容量
//特殊处理
if(string==nullptr || length<=0)
return ;
int num=0, origianlLen=0;
for(int i=0;i<=length;i++)
{
if(string[i] == ' ')
++num;
if(string[i] != '\0')
++origianlLen;
}
int newLen = origianlLen + 2*num;
if(newLen > length)
return ;
int indexOfNewLen = newLen;
int indexOfOrigianlLen = origianlLen;
while(indexOfOrigianlLen>=0 && indexOfNewLen>indexOfOrigianlLen)
{
if(string[indexOfOrigianlLen] == ' ')
{
string[indexOfNewLen--] = '0';
string[indexOfNewLen--] = '2';
string[indexOfNewLen--] = '%';
}
else
{
string[indexOfNewLen--] = string[indexOfOrigianlLen];
}
--indexOfOrigianlLen;
}
}
int main()
{
const int length = 20;
char string[length] = "We are happy.";
replaceBlank(string, length);
return 0;
}
举一反三:
对于两个已排好顺序的数组互相插入值时也是,从尾向头插入操作比较好;
合并两个数组也是。