问题描述

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

解题思路

涉及到字符串的拷贝问题。

1、最初的想法是设置一个字符串指针指向%20字符,原字符串中遇到空格字符后与%20字符串替换,再继续遍历原字符串,C++中的string类重载了+运算符,并且有很多关于字符串拼接替换查找等的函数模板,是可以实现的,但本题目的形参是char*类型的,显然不合题意。

2、下一个思路是重建一个足够长的字符串数组,将原字符串中的空格替换成%20的字符串并按照题意全部拷贝到新的字符数组中,虽然在VS里成功了,但是形参所指向的字符串没有发生变化,OJ系统报错。

3、只能通过修改函数参数str了。但是要知道,主函数中的实参一定是空间足够大的字符数组类型,不可能是指向字符串的指针,因为是指针的话,无法对指向的字符串进行修改和扩容,字符数组是完全可以修改内容的。

字符串数组和字符串指针的异同

1、字符指针所指向的内容不具有写入性,有只读属性,但是可以改变字符串指针的指向;字符数组中的数据是可以被写入的。

char* str = "I like you!";
str[3] = 'g'; // 这句话就是错的
str = "I know you!"; // 正确
puts(str3);

​str3[3] = 'g';​​这句话就是错的,无法对字符串的内容进行修改。

​str = "I know you!";​​这句话是正确的,因为指针可以改变它的指向。

字符数组:

char str[12] = "I like you!"; 
str[4] = 'u';
puts(str);//I liue you! 成功修改

显然, 字符数组中的元素是可以被修改的。

2、字符数组的大小至少是字符串内容大小加1,也就是数组中字符串的最后一位要存储\0,但求字符串长度的时候,不加\0。

char str[12] = "I like you!"; // 字符串的长度为11但是数组需要至少12个空间最后一位存储 '\0'
cout << strlen(str) << endl; // 显示的是11

该例题,要是写成`char str[11] = "I like you!"则 开辟空间不足 会报错。

3、遍历字符串两种类型的使用是一致的

字符串指针

char* str = "I like you!";
puts(str);
for (char *p = str ; *p; p++) // I l i k e y o u !
{
cout << *p << " ";
}
cout << endl;

这样是完全可以的

for (int i = 0; *(str + i); i++) //I   l i k e   y o u !
{
cout << *(str + i) << " ";
}
cout << endl;

字符数组

char str[12] = "I like you!"; 

for (int i = 0; str[i]; i++) //I l i k e y o u !
{
cout << str[i] << " ";
}
cout << endl;

这样也是完全可以的

for (int i = 0; i < strlen(str); i++)  //I   l i k e   y o u  !
{
cout << *(str + i) << " ";
}
cout << endl;

代码实现

class Solution {
public:
void replaceSpace(char *str,int length) {
int i = 0, num = 0;
for (i = 0; str[i]; i++)
{
if (str[i] == ' ')
{
num++; // 找到字符串中空格的个数
}
}
int newlength = length + num * 2; // 插入字符串后需要新的空间大小
str[newlength] = '\0'; // 记得最后一定要写终止符
int j = newlength - 1; // 数组下标总是比真实实物个数少1个
for (i = length - 1; i >= 0, j >= 0; i--, j--) // 从尾到头拷贝数据
{
if (str[i] == ' ') // 遇到空格则拷贝 %20
{
str[j] = '0';
str[--j] = '2'; // 先j--,再赋值
str[--j] = '%';
}
else
{
str[j] = str[i]; // 否则直接拷贝
}
}
}
};

下面再写一下用string类的情况,就很简单了

class Solution 
{
public:
void replaceSpace(string &str) // 使用string类的查找和插入
{
int pos = 0;
while (pos != -1) //find函数差找不到返回-1
{
pos = str.find(' ', pos); // pos从0位开始,每次查找空格字符的位置
if (pos == -1) // 如果已经查找不到了 直接返回-1 此时用break跳出循环
break;
str.replace(pos, 1, "%20"); // 将pos位往后的1位(空格本身)替换为%20
}
}
};

做这道题有等于把字符串的知识点复习了一遍,我真是个学渣。