剑指offer——替换空格

Posted shengguilv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer——替换空格相关的知识,希望对你有一定的参考价值。

数组类型的题目写的差不多了,接下来开始做字符串相关的,原题目链接:替换空格

为了方便直接阅读,还是先抄一下题目。

题目描述:

请实现一个函数,将一个字符串中的每个空格替换成"%20"。例如,当字符串为We Are Happy.则经替换后的字符串为We%20Are%20Happy。

 题目分析:

对于字符串相关的问题,通常都会做一下两点考虑

1.将字符串当作一个字符数组

2.对其中的字符,采用指针进行操作。

对于所给的这个例子,首先将其考虑为如图所示的情况:

 技术图片

接下来,需要使用指针来遍历该字符串,判断其中的某个字符是否为空格。如果是空格,那么就需要对该位置以及之后的所有位置元素进行移位等操作

在此题目中,是要求将空格替换成"%20"从长度上来看,就是用3个字符,替换1个字符;也就是说,出现1次空格,字符串的长度就要增加2;那么用指针遍历一次该字符串,就可以得到替换之后的字符串长度

接下来比较麻烦,那就是对字符进行移位。

移位可以先从前往后移:当前面出现空格时,将此处之后的所有元素向后移动;

也可以从后往前移:当后面出现空格时,将此处之后的所有元素向后移动;

由于我们可以得到替换之后字符串的总长度,那么如果从后往前移动,就会减少移动的次数。

所以此题目中关键是:要从后往前移动

 

移动的过程如下图所示:

技术图片

  就以题目所给的字符串“We Are Happy."为例;

首先是步骤(a)用一个指针P1从前往后遍历每个字符,获取空格字符的个数,当遍历到字符串的结束标志时,计算出需要增加的位数n,然后将指针P2从P1处向后移动n位。

然后是步骤(b)开始从后逐渐移动字符,将P1处的字符移动给P2,然后两个指针均向前移动1位;继续如此操作,直到P1移动到空格字符的位置

接着是步骤(c)指针P1始终指向空格位置,指针P2位置依次填入"0","2","%",每填入一个字符,P2就向前移动一下;填入这3个字符后,P1开始继续向前移动。

然后是步骤(d)对于字符中的其余位置和空格也都进行如步骤(b)和(c)的操作。

最后是步骤(e)直到P2和P1指向同一个位置时,字符串替换完毕。

实现代码如下所示:

技术图片
 1 public String replaceSpace(StringBuffer str) {
 2         if(str == null || str.length() <= 0){
 3             return str.toString();
 4         }
 5         int space_num = 0;    //字符中空格的个数
 6         for(int i=0; i<str.length(); i++){
 7             if(str.charAt(i) == ‘ ‘){
 8                 space_num++;
 9             }
10         }
11         if(space_num == 0){    //若没有空格,则不需要替换
12             return str.toString();
13         }
14         //Java中没有指针,但是有索引,类似于数组下标
15         int index_old = str.length() - 1;    //指向最后一个字符的位置
16         int index_new = index_old + space_num * 2;    //指向替换后的最后一个字符位置
17         str.setLength(index_new + 1);    //要重置一下str的字符串长度,不然会下标越界
18         while(index_old < index_new && index_old >= 0){
19             if(str.charAt(index_old) != ‘ ‘){    //若该位置不是空格,则直接设置到替换后的位置
20                 str.setCharAt(index_new, str.charAt(index_old));
21                 index_old--;
22                 index_new--;
23             }else{    //若该位置是空格,则将替换内容逐个加进去
24                 str.setCharAt(index_new, ‘0‘); index_new--;
25                 str.setCharAt(index_new, ‘2‘); index_new--;
26                 str.setCharAt(index_new, ‘%‘); index_new--;
27                 index_old--;
28             }
29         }
30         return str.toString();
31     }
View Code

此代码在牛客网上运行时间为17ms。

 在Java语言中,有个专门处理字符串的类,即StringBuffer

String与StringBuffer都可以存储字符串,但是String是字符串常量,不可以修改其中的单个字符;而StringBuffer是字符串变量,其中的字符是可以修改和扩充的。并且两者可以实现互换。

如果利用StringBuffer的体征,就不需要进行上述复杂的操作了,直接替换即可。

实现代码如下:

技术图片
 1     public String replaceSpace(StringBuffer str) {
 2         if(str == null){
 3             return null;
 4         }
 5         //创建一个空的StringBuffer
 6         StringBuffer newStr = new StringBuffer();
 7         for(int i=0; i<str.length(); i++){
 8             if(str.charAt(i) != ‘ ‘){    //如果str中的某个字符不是空格,则在newStr的末尾加入该字符
 9                 newStr.append(str.charAt(i));
10             }else{    //若出现空格,则依次向newStr末尾加入替换元素
11                 newStr.append(‘%‘);
12                 newStr.append(‘2‘);
13                 newStr.append(‘0‘);
14             }
15         }
16         return newStr.toString();    //将newStr转换成String返回
17     }
View Code

此代码在牛客网上的运行时间为20ms。

以上是关于剑指offer——替换空格的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer字符串面试题 替换空格

剑指offer 2.替换空格

剑指OFFER替换空格

替换空格-剑指Offer

[剑指offer] 替换空格

《剑指Offer》之替换空格