菜鸡程序猿第一次写博客
秋招结束后,处处不如意,为了更好的学习并记录,遂开始试着写写博客
第一篇博客,献给剑指offer
关于剑指offer题2(空格替换)的一些自己的看法
题目描述:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
因为本人学的是Java,一看到题目,立马想到String.replace()。
第一次提交的代码:
public String replaceSpace(StringBuffer str) {
return str.toString().replaceAll(" ", "%20");
}
AC了,时间12ms,空间9800k
由于以前在LeetCode中做过题,感觉12ms时间好长啊,想要优化,心想自己实现会不会效果好点,遂自己实现并提交
第二次提交的代码:
public String replaceSpace2(StringBuffer str) {
StringBuilder res = new StringBuilder();
for(int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c!=' ') {
res.append(c);
}else {
res.append("%20");
}
}
return res.toString();
}
啊哈~同样AC了,但是时间13ms,空间9824k,时间空间全大了,what 回事?
本着刨(jia)根(zhuang)问(xue)底(xi)的心态,alt+鼠标左键,源码如下:
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
这。。。这是啥?继续刨(jia)根(zhuang)问(xue)底(xi)。。。目测是通过正则表达式来进行替换的。。。。然后怎么个流程。。。。完全绕萌币了。。。绕了半天找到了替换方法,此处不粘代码了,发现和我代码不同的地方主要是在charAt处,官方应用的String对象,我用的是StringBuilder
是不是有什么关系?
因此第3次自己实现,代码如下:
public String replaceSpace3(StringBuffer str) {
String s = str.toString();
StringBuilder res = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(c != ' ') {
res.append(c);
}else {
res.append("%20");
}
}
return res.toString();
}
提交,AC,时间12ms,空间9706k,虽然时间没有优化,但是空间略微少了点。
思考:执行效率不是StringBuilder>StringBuffer>String 吗?为啥这道题改成了String反而更快了呢?
分析:
1)通过对比,发现主要区别在charAt()方法上,StringBuffer在调用的是父类AbstractStringBuilder的方法,该方法在会先检查下标是否越界,然后在进行返回
2)从线程安全方面看,StringBuffer是线程安全的,对应方法会进行加锁,StringBuilder和String是非线程安全的,可能这也有关。
就这样吧,也不知道分析的对不对,也不会进一步优化!
菜鸡程序猿就是我,我就是菜鸡程序猿!