剑指offer--面试题4:替换空格--Java实现

题目描述:
请实现一个函数,把字符串中的每个空格替换成”%20”。例如输入“We are happy”,输出“We%20are%20happy”。

解题思路:
在Java中有函数replace可以完成这个功能,我们先看一下源码中是怎么样实现的。

/**
     * Returns a string resulting from replacing all occurrences of
     * {@code oldChar} in this string with {@code newChar}.
     * <p>
     * If the character {@code oldChar} does not occur in the
     * character sequence represented by this {@code String} object,
     * then a reference to this {@code String} object is returned.
     * Otherwise, a {@code String} object is returned that
     * represents a character sequence identical to the character sequence
     * represented by this {@code String} object, except that every
     * occurrence of {@code oldChar} is replaced by an occurrence
     * of {@code newChar}.
     * <p>
     * Examples:
     * <blockquote><pre>
     * "mesquite in your cellar".replace('e', 'o')
     *         returns "mosquito in your collar"
     * "the war of baronets".replace('r', 'y')
     *         returns "the way of bayonets"
     * "sparring with a purple porpoise".replace('p', 't')
     *         returns "starring with a turtle tortoise"
     * "JonL".replace('q', 'x') returns "JonL" (no change)
     * </pre></blockquote>
     *
     * @param   oldChar   the old character.
     * @param   newChar   the new character.
     * @return  a string derived from this string by replacing every
     *          occurrence of {@code oldChar} with {@code newChar}.
     */
    public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

从jdk实现的源码中可以看到最后两个return语句,如果被替换的字符出现在了源字符串中,返回一个new String(),如果没有出现,则是返回了源字符串本身。

如果要求在源字符串上操作,前提是要求空间足够,可以采用这种思路:
1.暴力解法 从前向后遍历,每遇到空格,将后续的所有字符都向后移动,这样,对于前面有多个空格的字符,要移动多次,时间复杂度达到平方级别
2.首先找出空格的数量,然后就可以计算出后续的字符最终将移动到哪个位置,从后向前遍历移动。
这里只实现后者:


public class ReplcaceSapce {

    public static void replace(char[] str, int allLength){

        if(str == null && allLength <= 0){
            return;
        }

        //str中有效字符的个数,要减去最后一个'\0'
        System.out.println(str.length);
        int originalLength = 0;
        int i = 0;
        int blankCount = 0;
        while(str[i] != '\0'){
            originalLength++; 
            if(str[i] == ' '){
                blankCount++;
            }
            i++;
        }

        System.out.println("originalLength = " + originalLength);
        System.out.println("blankCount = " + blankCount);


        //从后往前复制
        int desLength = originalLength + blankCount * 2;
        if(desLength > allLength){
            return;
        }
        int indexOfOriginal = originalLength;
        int indexOfDes = desLength;

        while(indexOfOriginal >= 0 && indexOfDes > indexOfOriginal){
            if(str[indexOfOriginal] == ' '){
                str[indexOfDes--] = '0';
                str[indexOfDes--] = '2';
                str[indexOfDes--] = '%';
            }
            else{
                str[indexOfDes--] = str[indexOfOriginal];
            }
            indexOfOriginal--;
        }


    }

    public static void main(String[] args) {
        char[] string = new char[1024];
        //System.out.println("length = " + string);
        String s = "We are happy";
        for(int i = 0; i < s.length(); i ++){
            string[i] = s.charAt(i);

        }
        string[s.length()] = '\0';

        replace(string, 1024);
        for(int i = 0 ; i < 1024; i++){
            System.out.print(string[i]);
        }


    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值