剑指offer面试题:空格替换

      题目:实现一个函数,把每个空格替换成%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);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章