Java:用%20替换空格。为什么会打印%20 A而不是Mr%20A

时间:2017-03-05 14:00:59

标签: java algorithm

您好我正在尝试将String中的空格替换为%20。 例 输入:A先生 输出:%20A先生

我无法理解为什么我的代码正在打印“Mr%20 A”。我想打印“Mr%20A”,所以请告诉我该怎么做呢?这是我的代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestAnswer {



    public static void main(String[] args) {
        //System.out.println(isPermutation("aXbcx", "xbcaX"));
        System.out.println(URLify("Mr A"));
    }


    static String URLify(String s){
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
            char  c = s.charAt(i);
            if(c == ' '){
                sb.append("%20");

            }

            sb.append(c);

        }

        return sb.toString();
    }

}

4 个答案:

答案 0 :(得分:5)

不要循环String并使用StringBuilder重新创建它,而是考虑使用以下单行代码:

s = s.replace(" ", "%20");

答案 1 :(得分:4)

在您追加"%20"后(如果是c == ' '),您还会附加c

char  c = s.charAt(i);
if(c == ' '){
    sb.append("%20");
}
sb.append(c); //here

解决方案是仅在不c时附加' '

<强>解决方案:

char  c = s.charAt(i);
if(c == ' '){
    sb.append("%20");
}else{
    sb.append(c);
}

答案 2 :(得分:0)

通过评论

//System.out.println(isPermutation("aXbcx", "xbcaX"));

我可以看到你正在解决CTCI

@sudo回答了你的问题,我只是想提出一个更好的解决方案

你的解决方案可能已经足够好但是值得解释的是StringBuilder.append会使char数组大小加倍,如果容量不够,它将包含每个append的字符串,直到它可以保存字符串

我的解决方案将在原始字符串上迭代两次,但不会扩展返回的char数组

private static char[] URLify(char[] original) {
    char charToReplace = ' ';
    char[] replacement = new char[]{'%', '2', '0'};
    // count charToReplace, in our case, count spaces
    int numCharsToReplace = 0;
    for (char c : original) if (c == charToReplace) numCharsToReplace++;
    // creating new fixed char array to return
    int resultSize = original.length + (numCharsToReplace * replacement.length) - numCharsToReplace;
    char[] result = new char[resultSize];
    // we need two indexes,one to iterate the result char array, second to iterate the original
    int i = 0, originalIdx = 0;
    // until we set all new array of chars cells
    while (i < resultSize) {
        // get original character
        char curOriginalChar = original[originalIdx];
        // this condition is first because I assume real URL will not contain as much spaces as chars
        // if current character is not one we need to replace, copy
        if (curOriginalChar != charToReplace) {
            result[i] = curOriginalChar;
            // for readable code the index incremented in new line
            // could be replaced with "result[i++] = curOriginalChar;"
            i++;
        }
        else {
            for (char c : replacement) {
                result[i] = c;
                i++;
            }
        }
        originalIdx++;
    }
    return result;
}

获取StringBuilder真实字符串数组长度的实用程序

/**
 * StringBuilder's member "char value[]" is the character array stored inside StringBuilder, and it's
 * reference can be accessed only through getValue method, which is not public
 * so a little hack so we can know what is the char array size created
 */
private static int getStringBuilderCharSize(StringBuilder sb) throws NoSuchFieldException, IllegalAccessException {
    Field stringBuilderCharField = StringBuilder.class.getSuperclass().getDeclaredField("value");
    stringBuilderCharField.setAccessible(true);
    char[] chars = (char[]) stringBuilderCharField.get(sb);
    return chars.length;
}

用法示例

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        String original = "Mr & Mrs Smith";
        char[] urlify = URLify(original.toCharArray());
        System.out.println(new String(urlify) + "|" + urlify.length);

        StringBuilder sb = new StringBuilder();
        for (char c : original.toCharArray())
            if (c != ' ') sb.append(c);
            else sb.append("%20");
        System.out.println(sb.toString() + "|" + getStringBuilderCharSize(sb));
    }

输出:

Mr%20&%20Mrs%20Smith|20
Mr%20&%20Mrs%20Smith|34

保存了14个细胞;)

答案 3 :(得分:0)

在您的代码中,您正在检查字符是否为空格并在StringBuilder中附加“%20”。但是,if条件之后的sb.append(c)语句也会导致空格被附加。 您可以在if case中附加“%20”后添加continue关键字。

所以你的代码应该是这样的:

static String URLify(String s){
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
            char  c = s.charAt(i);
            if(c == ' '){
                sb.append("%20");
                continue;
            }

            sb.append(c);

        }

        return sb.toString();
    }