题目描述
请实现一个函数,把字符串的每一个空格替换成“%20”。例如,输入“we are happy”,则输出“we%20are%20happy”。
思路分析
首先,我们能到的办法就是从头遍历字符数组,遇到一个空格,将空格后面的字符串向后移动两位(‘%’,’2’,’0’),然后将空格替换成%20这三个字符,然后继续向后遍历字符串,遇到空格则将后面的字符移动两位,然后将空格替换成%20,直到字符串遍历结束,但是这种方法的效率太低了,找到第一个空格,将后面的字符串向后移动,时间复杂度为O(n),下次在遇到空壳做替换的时间复杂度也为O(n),所以这种算法的时间复杂度为O(n^2)。我们可以去尝试用更好的方法:
第一:首先查找字符数组中有多少个空格,假设有n个空格,替换一个空格需要增加2个长度,那么增加替换后数组的长度就是为原来的长度加上2*n
第二:字符数组从后面开始查找,如果遇到空格就使用“0”“2”“%”去替换,否则位置继续向前移动遍历字符串
代码实现
//length为给定字符数组的长度
void ReplaceBlank(char arr[], int length)
{
int OriginLength = 0;//记录源字符串的实际长度
int NewLength = 0;//记录替换后字符串长度
int count = 0;//记录空格的个数
int i = 0;
if (length <= 0)//给定数组长度为0则直接结束
{
return;
}
//计算空格的个数
while (arr[i] != '\0')
{
OriginLength++;
if (arr[i] == ' ')
{
count++;
}
i++;
}
//替换后字符串长度为源字符串长度加上2乘以空格个数
NewLength = OriginLength + 2 * count;
//替换后字符长度如果大于给定数组长度,则直接结束,负责越界访问
if (NewLength > length)
{
return;
}
//从源字符串最后开始遍历
for (i = OriginLength; (OriginLength >= 0) && (NewLength > OriginLength); i--)
{
//遇到空格则在向后移动的位置替换
if (arr[OriginLength] == ' ')
{
arr[NewLength--] = '0';
arr[NewLength--] = '2';
arr[NewLength--] = '%';
}
//否则向后移动
else
{
arr[NewLength--] = arr[OriginLength];
}
OriginLength--;
}
}