今天看题的时候,遇到一个替换空格的题目,分析一下哈。
题目要求:把字符串中的每个空格替换成“%20”。例如输入“we are happy”,则输出“we%20are%20happy”。
解题思路:我们首先想到的是:移位思想。遇到空格就将空格后的所有字符后移两位,然后填充空格为%20。
实现代码:
#pragma once
#include<assert.h>
#include<string.h>
char* StrReplace(char* str,size_t length)
{
assert(str && length > 0);
char *p = str;
char *p1 = str;
size_t len = strlen(str)+1;
size_t i = len;
while(p)
{
while(*p != ' ')
{
p++;
if(*p == '\0')
{
return str;
}
}
while((p1+i) != p)
{
*(p1+i+1) = *(p1+i-1);
i--;
}
len+=2;
i = len;
*p = '%';
*(p+1) = '2';
*(p+2) = '0';
p+=2;
}
return str;
}
void Test()
{
char str[20] = "we are happy";
cout<<StrReplace(str,20)<<endl;
}
但是,我们再看看它的时间复杂度哈。显然,每次移位操作都是O(N),这样经过多次移位,使它的时间复杂度就变为O(N^2)。这样的效率实在有点低。我们如何提高它的时间复杂度呢?
思路2:我们可以用计数的方式,统计字符串中总共的空格数,然后从后向前移位,使用两个指针,p1指向字符串开始的位置,p2指向字符串尾部,移位将p2移动2*空格个数位,遇到空格后填充,直到两指针相遇,才停止移位。如图所示(移位过程):
![这里写图片描述](https://img-blog.csdn.net/20170412202456298?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHhwcmVzZW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
实现代码:
#pragma once
#include<assert.h>
#include<string.h>
char* StrReplace(char* str,size_t length)
{
assert(str && length > 0);
char *p = str;
char *p1 = NULL;
char *p2 = NULL;
size_t len = strlen(str);
int count = 0;
while(*p != '\0')
{
if(*p == ' ')
count++;
p++;
}
count*=2;
p1 = str+len;
p2 = str+len+count;
while(p1 != p2)
{
if(*p1 == ' ')
{
p2 -= 2;
*p2 = '%';
*(p2+1) = '2';
*(p2+2) = '0';
if(p1 != p)
{
p1--;
p2--;
}
}
else
{
*p2 = *p1;
p1--;
p2--;
}
}
return str;
}
void Test()
{
char str[20] = "we are happy";
cout<<StrReplace(str,20)<<endl;
char str1[20] = " are happy";
cout<<StrReplace(str1,20)<<endl;
}
执行结果:
![这里写图片描述](https://img-blog.csdn.net/20170412205256358?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHhwcmVzZW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)