题目描述:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路:
- 使用插入操作不可取,移动的元素过多。
- 计算替换后的字符串的总长度。
- 增长字符串,达到替换后的总长度。
- 从后向前使用双指针依次替换, 从前往后替换会导致部分字符被覆盖。
问题:
- 对于C/C++的语言来说,它们的字符串就是一个很长的以’\0’结尾的字符数组,但是在java中并不是这样的,任何一个字符串都是String类的一个不可变对象,任何对于字符串的操作都相当于创建了一个新的字符串。
- 对于String、StringBuffer、StringBuilder三个类的底层实现还没有理解到位,需要继续学习,不然对于java中字符串的操作,创建的对象也太多了吧。
代码
public class ReplaceSpace {
public static String replaceSpace(StringBuffer str) {
int nBlank = 0; // 记录空格字符数目
int length = str.length();
for (int i = 0; i < length; i++) { // 统计空格字符数目
if (str.charAt(i) == ' ')
nBlank++;
}
int newLength = length + nBlank * 2; // 计算最终的字符串的长度
str.setLength(newLength); // 更新字符串的长度,这个方法的底层实现还不是特别了解。
int ptrOld = length - 1;
for (int ptrNew = newLength - 1; ptrNew >= 0;) {
if (str.charAt(ptrOld) == ' ') {
str.setCharAt(ptrNew--, '0'); // 这些对于字符串的操作是不是都会创建一个新的字符串对象呢???????
str.setCharAt(ptrNew--, '2');
str.setCharAt(ptrNew--, '%');
} else {
str.setCharAt(ptrNew--, str.charAt(ptrOld));
}
ptrOld--;
}
return str.toString();
}
public static void main(String[] args) {
StringBuffer str = new StringBuffer("We Are Happy");
StringBuffer str2 = new StringBuffer("I am learning Algorithms with java language. ");
System.out.println(replaceSpace(str));
System.out.println(replaceSpace(str2));
}
}
根据费曼学习法: 学习到的东西只有输出了才能巩固得更好。