题目:实现一个函数,把每个空格替换成%20,例如输入we are happy,输出we%20are%20happy。
解题思路一:我相信大家和我一样看到这道题的第一印象应该就是从头遍历数组,遇到空格就是将后面的字符向后移动,然后再插入字符,这样做虽然可以解决这个问题,但是遍历数组和向后移动字符一起进行会使时间复杂度变为O(n^2),并且移动过的代码会再次移动(比如happy,遇到第一个空格移动后遇到第二个空格还会移动)。这样虽然比较容易理解,但就比较费时。这里就不做代码演示了,我们可以重点看看思路二。
解题思路二:为了使时间复杂度低可以采用从后向前遍历数组的方式来替换空格。思想就是我们先确定替换后的字符串大小,然后从后遍历将先将happy移动到最终的位置,然后遇到空格插入'%20',再把are移动,然后遇到空格再次插入%20。这样就大大降低了时间复杂度,所有的字符也只移动了一次,提高了接替效率。
具体步骤:先遍历一次字符串,统计空格数目,然后计算出替换后字符串总长度。然后开辟新的大小的数组存放数据。定义两个指针p1,p2(为了实现字符的移动), 其中p1指向原字符串末尾,p2指向替换之后字符串末尾,向前移动p1,当*p1不是空格就逐个将其指向的字符复制到p2指向的空间,若遇到空格,p1向前移动1位,p2插入“%20”,相当于p2向前移动3位。
代码如下
#include <stdio.h>
#include <stdlib.h>
void instead(char *arr,int len)
{
int space=0;//统计空格的数量
int j=0;
while (j<len)
{
if(arr[j]==' ')
{
space++;
}
j++;
}
int newlen=len+space*2;
char *newarr=(char*)malloc(newlen*sizeof(char));//开辟新的大小的数组
int i=0;
while(i<len)
{
newarr[i]=arr[i];//将数据拷贝到新数组
i++;
}
char *p1=&newarr[len-1];//指向原始字符的末尾
char *p2=&newarr[newlen-1];//指向替换字符的末尾
while(p1!=p2)
{
if(*p1!=' ')
{
*p2--=*p1--;//没遇到空格就把字符放到后边
}
else//遇到空格p1向前一格,p2把%20插入,相当于移动三格。
{
*p2--='0';
*p2--='2';
*p2--='%';
p1--;
}
}
for(int i=0;i<newlen;i++)//打印替换后的字符串
{
printf("%c",newarr[i]);
}
free(newarr);
}
int main()
{
char arr[]="we are happy";
int n=sizeof(arr)/sizeof(arr[0]);
instead(arr,n);
}