题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入"We are happy",则输出"We%20are%20happy"。
思路:
1.先计算新数组总的长度,由于空格换成"%20",所以每个空格会额外多出两个字符。所以新的长度 = 原来长度 + 空格数 * 2。
2.准备两个指针P1, P2。P1指向原始字符串的末尾,P2指向新字符串的末尾。
3.接下来向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到了第一个空格为止。碰到第一个空格后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也需要把P2向前移动3格。
4.反复操作3步骤,当P1和P2指向同一个位置时,表明所有空格都已经替换完毕。所有的字符都只复制(移动)一次,所以时间复杂度为O(n)。
测试用例:
1.输入的字符串中包含空格(空格位于字符串的最前面,最后面,以及中间,以及有连续多个空格)
2.输入的字符串中没有空格。
3.特殊输入测试(字符串是个NULL指针、字符串是个空字符串、字符串只有一个空格字符、字符串中只有连续多个空格)。
代码:
#include<iostream>
#include<cstring>
using namespace std;
//length 为字符数组 string的总容量
void ReplaceBlank(char string[], int length)
{
if (string == NULL || length <= 0)
{
return;
}
//originalLength为字符串string的实际长度
int originalLength = 0;
int numberOfBlank = 0;
int i = 0;
while(string[i] != '\0')
{
++originalLength;
if (string[i] == ' ')
{
++numberOfBlank;
}
++i;
}
//newLength为替换空格之后新的长度
int newLength = originalLength + numberOfBlank * 2;
if (newLength > length)
{
return;
}
int indexOfOriginal = originalLength; //指针P1
int indexOfNew = newLength; //指针P2
while (indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
{
if (string[indexOfOriginal] == ' ')
{
string[indexOfNew--] = '0';
string[indexOfNew--] = '2';
string[indexOfNew--] = '%';
}
else
{
string[indexOfNew--] = string[indexOfOriginal];
}
--indexOfOriginal;
}
}
void Test(char str[], int length, char expected[])
{
ReplaceBlank(str, length);
if(expected == NULL && str == NULL)
cout << "passed" << endl;
else if(expected == NULL && str != NULL)
cout << "failed" << endl;
else if(strcmp(str, expected) == 0)
cout << "passed" << endl;
else
cout << "failed" << endl;
}
void Test1()
{
const int length = 100;
char str[length] = "hello world";
Test(str, length, "hello%20world");
}
void Test2()
{
const int length = 100;
char str[length] = "helloworld";
Test(str, length, "helloworld");
}
//空指针
void Test3()
{
Test(NULL, 0, NULL);
}
//空字符串
void Test4()
{
const int length = 100;
char str[length] = "";
Test(str, length, "");
}
int main()
{
Test1();
Test2();
Test3();
Test4();
return 0;
}
相关题目:
有两个排序的数组A1 和 A2,内存在A1的末尾有足够多的剩余空间容纳A2。请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字是排序的。
方法:从尾刀头比较A1 和 A2中的数字,并把较大的数字复制到A1的合适位置。
举一反三:
合并两个数组(包括字符串)时,如果从前往后复制每个数字(或字符)需要重复移动多次,那么我们可以考虑从后往前复制,这样就能减少移动的次数,从而提高效率。