从指定基数到BigInteger的高效转换

时间:2016-01-26 17:06:33

标签: java binary biginteger

我有一个输入:

20//radix, radix is less than 10000
19 13 0 18 13 19 15 12 19 3 12 19 2 10 19 14 16 7 1 1 18 5 12 7 5 8 7 19 8 0 16 10 13 1 11 11 7 10 19 9 //number in 20 radix

这是一个20基数。我想转换为BigInteger

这种方法非常缓慢:

BigInteger val = BigInteger.ZERO;
BigInteger radix = new BigInteger(br.readLine());
String line = br.readLine().split(" ");
    for (int i = 0; i < line.length; i++) {
        BigInteger digit = new BigInteger(line[i]);
        val = val.add(digit.multiply(radix.pow(line.length - 1 - i)));
    }

我尝试了,但它会抛出NumberFormatException

    String valAsString = br.readLine();
    BigInteger val = new BigInteger(valAsString, radix);
    System.out.println(val);

这会产生错误的结果:

String valAsString = br.readLine().replace(" ", "");
BigInteger val = new BigInteger(valAsString, radix);
System.out.println(val);

1 个答案:

答案 0 :(得分:1)

如果您将数字序列转换为单个字符串,则可以让BigInteger为您完成所有操作。

// Effectively all base-36 digits ordered for their value.
private static final String digits = "0123456789abcdefghijklmnopqrstuvwxyz";

public static BigInteger asBigInteger(String number, int radix) {
    if (radix <= digits.length()) {
        // Convert the number into a true radix-20 string.
        StringBuilder sb = new StringBuilder();
        for (String s : number.split(" ")) {
            sb.append(digits.charAt(Integer.valueOf(s)));
        }
        return new BigInteger(sb.toString(), radix);
    } else {
        BigInteger v = BigInteger.ZERO;
        BigInteger r = BigInteger.valueOf(radix);
        for (String s : number.split(" ")) {
            // Multiply by radix and add value.
            v = v.multiply(r).add(new BigInteger(s));
        }
        return v;
    }
}

public void test() {
    String number = "19 13 0 18 13 19 15 12 19 3 12 19 2 10 19 14 16 7 1 1 18 5 12 7 5 8 7 19 8 0 16 10 13 1 11 11 7 10 19 9";
    System.out.println(asBigInteger(number, 20));
    System.out.println(asBigInteger(number, 40));
}