双指针算法。
朴素思想是顺序查找,查找到了之后再进行移动替换。时间复杂度是O(n²)。
更优秀的O(n)解法是,先遍历一遍,找出空格的个数,进而可以得出替换后的字符串长度,用双指针P1,P2。
P1指向原字符串的最后一位字符,P2指向替换后字符串的最后一位(目前为空)。P1、P2开始从后往前,边移动边复制,直到P1遇到了空格,P2添加%20之后,继续双指针移动。
char* ReplaceBlank(char string[], int length) {
if (string == nullptr || length <= 0) {
return nullptr; // 返回 nullptr 而不是直接 return
}
int blank_cnt = 0;
for (int i = 0; i < length; i++) {
if (string[i] == ' ') blank_cnt++;
}
int new_length = length + 2 * blank_cnt;
char* new_str = new char[new_length + 1]; // +1 用于 '\0'
int p2 = new_length - 1;
int p1 = length - 1;
while (p1 >= 0 && p2 >= 0) {
if (string[p1] != ' ') {
new_str[p2--] = string[p1--];
} else {
new_str[p2--] = '0';
new_str[p2--] = '2';
new_str[p2--] = '%';
p1--;
}
}
new_str[new_length] = '\0';
return new_str;
}
另tag:
悬垂指针:悬垂指针是指指针指向的内存已经被释放或失效,但指针本身仍然保留原来的地址。例如:
int* func() {
int arr[5] = {1, 2, 3, 4, 5}; // 局部数组,函数结束后被销毁
return arr; // 返回悬垂指针!
}
int main() {
int* ptr = func(); // ptr 现在指向已被释放的内存
std::cout << ptr[0]; // 未定义行为(可能崩溃或输出垃圾值)
return 0;
}