剑指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 }
此代码在牛客网上运行时间为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 }
此代码在牛客网上的运行时间为20ms。
以上是关于剑指offer——替换空格的主要内容,如果未能解决你的问题,请参考以下文章