题目描述
请实现一个函数,将一个字符串中的空格替换成“%20”。
例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
/*输入:字符串
输出:将空格替换成%20的字符串
思路:从右到左遍历字符串,找到空格的时候,记录空格个数,替换成%20
*/
public class Solution {
public String replaceSpace(StringBuffer str) {
int strlength = str.length();
int n = 0;//统计空格数目
for (int i=strlength-1;i>=0 ;i-- )
{
if(str.charAt(i)==' ')
n++;
}
int j = strlength+n*2-1;//指向变化后的数组指标
str.setLength(j+1); //没有这一步的话,会有数组越界的问题
for (int i=strlength-1;i>=0 ;i-- )
{
if(str.charAt(i)==' ')
{
str.setCharAt(j--,'0');
str.setCharAt(j--,'2');
str.setCharAt(j--,'%');
}
else str.setCharAt(j--,str.charAt(i));
}
return str.toString();
}
}
知识点
1、String、StringBuffer、StringBuilder的区别:
牛客网给出的解答模板是传入一个StringBuffer的参数,就顺带做一下这三个类的比较。
- String:字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'}; String str = new String(data);
- StringBuffer:线程安全的可变字符序列。一个类似于
String
的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。 - StringBuilder:每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为StringBuffer类补充了一个单个线程使用的等价类,即
StringBuilder
。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
网上的一个总结:
速度:StringBuilder>StringBuffer>String
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
——————————————————————————————————————————————
2、代码中用到的几个字符串常用函数
以下是三种字符串类都拥有的常用方法:
charAt(int index)
返回此序列中指定索引处的char
值。substring(int start, int end)
返回一个新的String
,它包含此序列当前所包含的字符子序列。toString()
返回此序列中数据的字符串表示形式
以下是StringBuffer和StringBuilder类在本题中用到的方法:
Ps:挺有趣的是,这道题用Java的话有一个内置函数就能直接AC,时间空间都符合要求,也不需要考虑从后开始遍历字符串等。那就是String类的replace函数哈哈哈。顺带马克一下replace函数吧
replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar
替换此字符串中出现的所有 oldChar
得到的。
replaceAll(String regex, String replacement)