题意
给定一个字符串,将其中的所有空格都替换成”%20”三个字符,比如“I am happy.”将会变成”I%20am%20happy.”,假设给定的指针所指向的内存是够用的,然后O(1)空间和O(n)时间。
思路
先统计空格的个数,就能够建立起老的字符到新的位置的映射了。
主要是觉得书里的代码写得效率不高,所以po一下代码:
#include <iostream>
using namespace std;
void replaceBlank(char* str) {
// 处理空指针的异常
if (str == NULL)
return;
int countOfSpace = 0;
char* now = str;
while (*now != '\0') {
if (*now++ == ' ')
++countOfSpace;
}
// 一个小细节
if (countOfSpace == 0)
return;
char* newStr = now + (countOfSpace << 1);
while (now >= str) {
if (*now == ' ') {
*newStr-- = '0';
*newStr-- = '2';
*newStr-- = '%';
} else {
*newStr-- = *now;
}
--now;
}
}
int main() {
char str1[] = "hello jacket, good night\0aaaaaaaaaa";
cout << str1 << endl;
replaceBlank(str1);
cout << str1 << endl;
return 0;
}
为什么我说书里的代码不够优化呢?有两点吧:
1. 没有给出countOfSpace等于0优化;
2. 对于字符的操作是通过str[index]来引用的,这个其实比直接用指针多了一点计算,因为str[index] = str + index*sizeof(char)。
关于优化的评价
对于第1点,其实得看场景的,如果输入都是有空格的,那么这个判断就没必要了。
对于第2点,编译器或许会对循环进行优化,所以也不是大问题。
不过在不影响可读性的情况下,我还是会喜欢用不依赖编译器优化就可能提高效率的写法。
最近有个朋友跟我说,java代码会在编译的时候自动优化的,不要花力气帮编译器做事啊^_^萝卜青菜吧