替换空格
题目:
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
- 书上此题本意是让我们从后往前移动字符以达到o(n)复杂度,StringBuffer的出现的意思就是让我们在原字符串上面修改。所以要熟悉StringBuffer和StringBuilder里的方法才能快速写出。这里要注意的点是修改str的长度。
- 之间写的时候犯了一个错误,将while循环那里将i–写进了两个charAt()里面导致越界。
public class Solution {
public String replaceSpace(StringBuffer str) {
if (str == null) return str.toString();
int oldLen = str.length();
int numOfBlank = 0;
for (int i = 0; i < oldLen; ++i) {
if (str.charAt(i) == ' ') {
++numOfBlank;
}
}
if (numOfBlank == 0) return str.toString();
int newLen = oldLen + numOfBlank*2;
str.setLength(newLen);
int i = oldLen - 1;
int j = newLen - 1;
while (i >= 0) {
if (str.charAt(i) == ' ') {
str.setCharAt(j--, '0');
str.setCharAt(j--, '2');
str.setCharAt(j--, '%');
} else {
str.setCharAt(j--, str.charAt(i));
}
--i;
}
return str.toString();
}
}
- 这里一句代码虽然简单,但是肯定冗余了,也肯定不是出题人的本意,这样写应该过不了面试。但是也应该看下其中原理。于是翻看了这里使用的replace源码。
public class Solution {
public String replaceSpace(StringBuffer str) {
return str.toString().replace(" ", "%20");
}
}
源码分析:这里使用StringBuilder新建了一个对象从头开始复制过来,总的来说时间上比上面慢了一点点,并且多用了空间。
public String replace(CharSequence target, CharSequence replacement) {
String tgtStr = target.toString();
String replStr = replacement.toString();
int j = indexOf(tgtStr);
if (j < 0) {
return this;
}
int tgtLen = tgtStr.length();
int tgtLen1 = Math.max(tgtLen, 1);
int thisLen = length();
int newLenHint = thisLen - tgtLen + replStr.length();
if (newLenHint < 0) {
throw new OutOfMemoryError();
}
StringBuilder sb = new StringBuilder(newLenHint);
int i = 0;
do {
sb.append(this, i, j).append(replStr);
i = j + tgtLen;
} while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
return sb.append(this, i, thisLen).toString();
}