替换空格

基础知识

C/C++中每个字符串都以字符'\0'作为结尾,这样我们就能很方便地找到字符串的最后尾部。但由于这个特点,每个字符串中都有一个额外字符的幵销,稍不留神就会造成字符串的越界

 

Java里面一切都是對象,是對象的話,字符串肯定就有长度,即然有长度,编译器就可以確定要輸出的字符个数,当然也就沒有必要去浪費那1字节的空间用以表面字符串的結束了。

 

在网络编程中,如果URL参数中含有特殊字符,如空格、’#'等,则可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符。转换的规则是在'%’后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换成"%20"。再比如'#'的 ASCII码为35,即十六进制的0x23,它在URL中被替换为"%23"。

 

原来一个空格字符,替换之后变成’%’、’2'和’0’这 3 个字符,因此字符串会变长。如果是在原来的字符串上进行替换,就有可能覆盖修改在该字符串后面的内存。如果是创建新的字符串并在新的字符串上进行替换,那么我们可以自己分配足够多的内存。由于有两种不同的解决方案,我们应该向面试官问清楚,让他明确告诉我们他的需求。假设面试官让我们在原来的字符串上进行替换,并且保证输入的字符串后面有足够多的空余内存。

问题

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

1、思路

最简单的方法就是从头到尾遍历,但是时间复杂度为O(n^2)。

本文采用一种时间复杂度为O(n)的方法。

我们可以先遍历一次字符串,这样就可以统计出字符串空格的总数,并可以由此计算出替换之后的字符串的总长度。每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。以"We are happy"为例,"We are happy"这个字符串的长度为14(包括结尾符号"\n"),里面有两个空格,因此替换之后字符串的长度是18。

我们从字符串的尾部开始复制和替换。首先准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。接下来我们向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。碰到第一个空格之后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也要把P2向前移动3格。

移动示意图:

import java.util.Arrays;
import java.util.Scanner;
/**
 * @Auther: liuhaidong
 * Data: 2019/10/10 0010、9:22
 * Description:
 * @version: 1.0
 */
public class InsteadOfSpace {
    public static void main(String[] args) {
        System.out.println("请输入一个字符串");
        Scanner sc = new Scanner(System.in);
        System.out.println(insteadOf(sc.nextLine()));
    }

    private static String insteadOf(String s) {
        if(s == null){
            return "";
        }
        int count =0;
         for(int i =0;i<s.length();i++){
             if(s.charAt(i) == ' '){
                 count ++;
             }
         }
         //计算出长度
         char[] newString = new char[s.length()+count*2];
         for(int i =0;i<s.length();i++){
             newString[i] = s.charAt(i);
         }
         //对新的字符串赋值
         int a = s.length()-1;
         //指针p1的位置
        int b = newString.length-1;
        //指针p2的位置
        while (a != b){
            while(' ' != newString[a]){
                  newString[b] = newString[a];
                a--;
                b--;
            }
            newString[b] = '0';
            newString[--b] = '2';
            newString[--b] = '%';
            a--;
            b--;
        }
         return Arrays.toString(newString);
    }

}

2、思路

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


思路:新定义一个往后追加。
public class Solution {
    public String replaceSpace(StringBuffer str) {
    	StringBuffer newstr = new StringBuffer();
        for(int i = 0;i<str.length();i++)
        {
            if(str.charAt(i) != ' ')
            {
                newstr.append(str.charAt(i));
                
            }
            else
            {
                newstr.append("%20");
            }
        }
        return newstr.toString();
    }
}

3 大神的代码

import java.util.Scanner;

/**
 * @author FengTianHao
 * @version 1.0
 * @since 2018/11/30 11:07
 *
 */
public class Test {
    public String replaceSpace(StringBuffer str) {

        if(str==null||str.length()==0)
        {
            return str.toString();
        }
        int numberOfBlank=0;//空格的数量
        for(int i=0;i<str.length();i++)
        {
            if(str.charAt(i)==' ')
            {
                numberOfBlank++;
            }
        }
        int indexOfOriginal=str.length()-1;//指向旧字符串的最后一个字符
        int newlength=str.length()+numberOfBlank*2;//计算新字符串的长度
        str.setLength(newlength);//将旧字符串的空间扩大
        int indexOfNew=str.length()-1;//指向新字符换的最后一个字符
        for(;indexOfOriginal>=0&&indexOfNew>indexOfOriginal;--indexOfOriginal)
        {
            if(str.charAt(indexOfOriginal)==' ')//当前字符为空格时
            {
                str.setCharAt(indexOfNew--,'0');
                str.setCharAt(indexOfNew--,'2');
                str.setCharAt(indexOfNew--,'%');
            }
            else//当前字符不为空格时
            {
                str.setCharAt(indexOfNew--,str.charAt(indexOfOriginal));
            }
        }

        return str.toString();
    }

    public static void main(String[]args) {
        StringBuffer str=new StringBuffer(" We are happy.");
        System.out.println(new Test().replaceSpace(str));
    }
}