替换空格
题目描述
| 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 |
思路1
程序1(java)
/**
* code1
*调用函数直接替换
*/
public class Solution {
public String replaceSpace(StringBuffer str) {
return str.toString().replace(" ", "%20");
}
}
/**
* code2
*从后往前
*/
public class Solution {
public String replaceSpace(StringBuffer str) {
if(str==null){
return null;
}
int count=str.length();
for(int i=count-1;i>=0;i--){
if(str.charAt(i)==' '){
str. deleteCharAt(i);
str.insert(i,"%20");
}
}
return str.toString();
}
}
/**
* code3
*从前往后
*/
public class Solution {
public String replaceSpace(String str) {
if (str == null) {
return null;
}
StringBuffer outputBuffer = new StringBuffer();
for (int i = 0; i <str.length(); i++) {
if (str.charAt(i) == ' ') {
outputBuffer.append("%20");
} else {
outputBuffer.append(String.valueOf(str.charAt(i)));
}
}
return new String(outputBuffer);
}
}
思路2
- 先统计空格数量,计算出替换后的字符串长度。采用两个索引p1和p2,初始时分别指向旧字符串和新字符串的最后一个字符的下标,然后开始从后先前遍历字符串(java字符串末尾没有‘\0’),逐个将p1指向的字符复制到p2指向的位置,直到碰到第一个空格为止。碰到第一个空格后,把p1向前移动一格,在p2之前插入字符串“%20”,由于“%20”的长度为3,同时也要把p2向前移动3格。如此重复,直至p1和p2指向同一位置。如下图所示。
(a). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
w e a r e h a p p y
p1 p2
(b). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
w e a r e h a p p y
p1 p2
(c). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
w e a r e % 2 0 h a p p y
p1 p2
(d). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
w e a r e % 2 0 h a p p y
p1 p2
(e). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
w e % 2 0 a r e % 2 0 h a p p y
p1
p2
程序2(java)
/**
* code1
* 牛客网
* 时间复杂度O(n)
*/
public class Solution {
public String replaceSpace(StringBuffer str) {
if (str == null||str.length()<=0) {
return str.toString();
}
int count = 0;
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' '){
count++;
}
}
int p1=str.length()-1;
int p2=count*2+str.length()-1;
str.setLength(count*2+str.length());//将旧字符串的空间扩大
while(p1>=0&&p1!=p2){
if(str.charAt(p1)==' '){
str.setCharAt(p2--,'0');
str.setCharAt(p2--,'2');
str.setCharAt(p2--,'%');
p1--;
}else{
str.setCharAt(p2,str.charAt(p1--));
p2--;
}
}
return str.toString();
}
}
补充
String、StringBuffer、StringBuilder:
- String : 是java.lang包中的immutable类,String里面所有的属性几乎也是final,由于它的不可变性,类似拼接,裁剪字符串等动作都会产生大量无用的中间对象。由于字符串操作在项目中很常见,所以对String的操作对项目的性能往往有很明显的影响。
- StringBuffer : 这个类是为了解决String拼接产生多余对象的问题而提供的一个类。StringBuffer保证了线程的安全,也带来了多余的开销。
- StringBuilder : StringBuilder的功能与StringBuffer一样。但是区别是StringBuilder没有处理线程安全,减少了开销。
区别
- String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
- 使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
参考:
- Java:String、StringBuffer和StringBuilder的区别
- java中的StringBuffer和StringBuilder的用法,系统关键字之间的区别