替换空格
问题描述:
- 请实现一个函数,将一个字符串中的所有空格替换成“%20”
- 这道题其实本身没有说清楚是针对于字符串还是针对于字符串数组,所以这里分类进行讨论
算法思路一:
- 如果是字符串,对于java语言来说,这道题有一个非常容易的解法,那就是直接使用String类的replaceAll方法,但是实际上面试算法都是考查能力的,不会让你直接用接口写
- 但是我们可以自己去实现replaceAll中的源码来回答这个问题,用StringBuild,只需要遍历该字符串,根据题目要求构建返回一个新的字符串即可!
- 这个算法的时间复杂度也是O(n)的,所以也是比较好的!
public static String replaceStr(String str){
StringBuilder result = new StringBuilder("");
for(int i = 0; i < str.length(); i++){
if(str.charAt(i) == ' '){
result.append("%20");
}else {
result.append(str.charAt(i));
}
}
return new String(result);
}
算法思路二:(针对于c,c++)
-
但是如果是字符数组,就显然没有这么容易了,当然将字符数组先转化为字符串进行操作,然后再转回来也不失为一种不错的解法,这里还给出另外一种解法
-
如果从头开始遍历,每次遇见空格就替换“%20”,这样就会导致每次要多增加两个容量的位置,所以每次替换的时候都需要将后面的字符全部移两个位置,这样的算法复杂度太高了,并且一般情况下不会设计这样的算法。
-
为了不进行元素的移动,我们可以尝试从尾部开始遍历,如果从尾部开始遍历,如果遇见空格替换就不需要进行元素的移动了
-
但是实现这种算法的前提是我们必须控制好字符数组的容量,知道尾部在哪里。
所以我们必须提前遍历字符数组,找出所有空格的数量,然后就可以求出我们转换后结果的字符数组的容量,再从这个尾部开始遍历即可 -
为什么说这种算法只针对于c语言和c++呢?因为c语言和c++的字符数组尾部结尾都是以‘/0’结尾,并且字符数组的最大容量可以和实际存储容量不同。但是实际上java中一般不会有字符数组的结尾,一般都是动态定义初始化的!
public static void ReplaceBlank(char[] target, int maxLength)
{
if (target == null || maxLength <= 0)
{
return;
}
// originalLength 为字符串target的实际长度
int originalLength = 0;
int blankCount = 0;
int i = 0;
while (target[i] != '\0')
{
originalLength++;
// 计算空格数量
if (target[i] == ' ')
{
blankCount++;
}
i++;
}
// newLength 为把空格替换成'%20'之后的长度
int newLength = originalLength + 2 * blankCount;
if (newLength > maxLength)
{
return;
}
// 设置两个指针,一个指向原始字符串的末尾,另一个指向替换之后的字符串的末尾
int indexOfOriginal = originalLength;
int indexOfNew = newLength;
while (indexOfOriginal >= 0 && indexOfNew >= 0)
{
if (target[indexOfOriginal] == ' ')
{
target[indexOfNew--] = '0';
target[indexOfNew--] = '2';
target[indexOfNew--] = '%';
}
else
{
target[indexOfNew--] = target[indexOfOriginal];
}
indexOfOriginal--;
}
}