剑指offer系列02✨替换空格问题
Posted 爱生活爱编程a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer系列02✨替换空格问题相关的知识,希望对你有一定的参考价值。
💫题目介绍:
请实现一个函数,把字符串的每个空格替换为"%20"。例如输入"we are happy.",则输出为"we%20are%20happy."。
💡思路1:
这个题目我们很容易就会想到可以创建一个空间足够大的数组,然后将源数组依次进行拷贝,当遇到空格时将%20放入新数组中然后进行相应的偏移就可以实现。
代码实现:
#include <stdio.h>
#include <string.h>
#include <assert.h>
void replace(char* arr, char* arr1)
{
assert(arr && arr1);//判断输入有效性
while (*arr != '\\0')
{
if (*arr != ' ')
{
*arr1 = *arr;
arr1++;
}
else
{
strncpy(arr1, "%20", 3);
arr1 += 3;
}
arr++;
}
}
int main()
{
char arr[40] = "abc defgx yz";
char arr1[40] = { 0 };
replace(arr, arr1);
printf("%s\\n", arr1);
return 0;
}
结果:
💡思路2:
如果不允许创建新数组只能在原字符数组的基础上进行扩展的话,首先我们可以考虑从头到尾进行一次遍历字符串,每当我们遇到空格的时候,我们需要先将空格后面的字符串进行右移这样才能有足够的空间来放%20,当下一次遇到空格的时候我们同样需要这样操作。直到字符串遍历完成结束循环。
注意:
假设字符串长度为n。对每个空格字符,需要移动后面O(n)个字符,因此对含有O(n)个空格的字符串而言总共的时间复杂度为O(n^2)(需要用到嵌套循环)。
💡思路3:(最优)
由于上一个思路实现起来较为复杂,所以我们这里有一个更高效简单的方法来实现。首先我们遍历字符串然后计算出空格数并计算出从原字符串开始到原字符串的末尾(即指向’\\0’)的偏移量a,然后们通过空格数计算出扩展后的字符串长度和相应的偏移量b。第二步我们从后往前遍历,若不为空格则
根据偏移量进行赋值
并将偏移量减一(这里用到了arr[i] = *(arr+i), i为偏移量)
;若为空格则利用偏移量b将%20放到相应位置然后减一,然后将偏移量a减一。直到偏移量小于0结束循环。
代码实现:
#include <stdio.h>
#include <assert.h>
void add_arr(char* arr, int capacity)
{
assert(arr && capacity>0);//判断输入有效性
int initpoint = 0;
int newpoint = 0;
int num = 0;
while (arr[initpoint] != '\\0')
{
initpoint++;
if (arr[initpoint] == ' ')
{
num++;
}
}
newpoint = initpoint + 2 * num;//分别找到原字符串'\\0'的偏移量和扩展后的字符串'\\0'的偏移量
if (newpoint > capacity)
{
return;
}//判断数组空间够不够放下扩展后的字符串,若不够会直接退出函数从而打印原字符串
while (initpoint >= 0 && newpoint > initpoint)
{
if (arr[initpoint] == ' ')
{
arr[newpoint--] = '0';
arr[newpoint--] = '2';
arr[newpoint--] = '%';
}
else
{
arr[newpoint--] = arr[initpoint];
}
initpoint--;
}//从后往前进行替换
}
int main()
{
char arr[40] = "we are happy.";
add_arr(arr,40);
printf("%s\\n", arr);
return 0;
}
结果:
该思路时间复杂度为O(n)。
作者水平有限,若文章有任何问题欢迎私聊或留言,希望和大家一起学习进步!!!
创作不易,再次希望大家👍支持下,谢谢大家🙏
以上是关于剑指offer系列02✨替换空格问题的主要内容,如果未能解决你的问题,请参考以下文章
剑指 Offer(C++版本)系列:剑指 Offer 05 替换空格
剑指 Offer(C++版本)系列:剑指 Offer 05 替换空格