题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
两个解决方案:
分配的空间足够时,在原来的字符串上做替换;
分配空间不够时,需要 创建新的字符串并在新的字符串上做替换。
1、常见思路:从前到后遍历,遇到空格的时候就替换,由于必须将一个字符替换为三个字符,必须将后面的字符全部后移两个字节,否则就会有字符被覆盖。假设字符串长度为n.对每个空格而言需要移动O(n) 个字符,因此对于含有n个空格的字符串而言总的时间效率是O(n^2)。
2、O(n) 解题思路:遍历字符串,找到空格的数量,增长字符串的长度用以存放转换后的字符串。然后从后向前开始复制和替换。首先设置两个指针P1和P2,P1指向原始字符串的末尾,P2指向替换后的字符串的末尾。向前移动指针P1,逐个将它所指向的字符复制到P2指向的位置,直到碰到一个空格位置。碰到空格后,将P1向前移动一位,在P2逐个插入‘%’,‘2’,‘0’,此时P2向前移动3个字符。移动直到两个指针相等为止,即满足P2>P1时移动。此时所有字符都只需要移动一次,因此算法的效率为O(n)。
注意事项:%20是三个字符而空格只有一个字符,所以发生转换时会出现字符串移位现象。所以相对来说倒序存放可以避免每修改一次就需要将后面的字符向后移动。
class Solution {
public:
void replaceSpace(char *str,int length) {
int numblack=0; //用于计算字符串中空格的数目
char* ptr=str; //用于暂存该字符串
int oldlen=strlen(str); //字符串原来长度
if(str==0&&length<=0){ //当字符串为空时返回
return;
}
while(*ptr) { //遍历字符串,找出空格的数目
if(*ptr==' '){
numblack++;
}
ptr++;
}
if(numblack==0) { //当空格的数目为0时,说明不需要做任何改变,故返回
return;
}
int newlen=oldlen+2*numblack; //将空格转换成%20时,相当于在空格处插入三个字符,字符串的的长度会变长
while(oldlen<newlen) {
if(str[oldlen]==' '){ //从后依次赋值字符串,遇到空格则转换成%20
str[newlen--]='0';
str[newlen--]='2';
str[newlen--]='%';
oldlen--;
}else {
str[newlen--]=str[oldlen--];
}
}
}
};