什么是最有效的算法/代码来反转一个非常大的整数?

时间:2016-07-20 18:19:37

标签: java algorithm

我正在尝试使用最有效的算法来反转Java中的大整数。 例如。如果我们必须撤销301324354432。

直到现在我有以下代码:

public int reverse(int x) {
        int result = 0;
        while (x != 0)
        {
            int tail = x % 10;
            int newResult = result * 10 + tail;
            if ((newResult - tail) / 10 != result)
            { return 0; }
            result = newResult;
            x = x / 10;
        }
        return result;
    }

在最佳时间复杂度下实现此目标的正确算法是什么?

3 个答案:

答案 0 :(得分:3)

一种有效的方法是如下所示(类似于你的建议)。

public static long reverse(long x) {
    long y = 0;
    while(x > 0) {
        y = y * 10 + x % 10;
        x = x / 10;
    }
    return y;
}

这避免了昂贵的字符串转换,只有一个通过数字并且不使用任何内存(除了存储结果)。

修改

一种更有效的方法,避免除法和模运算:

public static long reverse(int _x) {
    long x = _x;
    long y = 0;
    while (x > 0) {
        y = x + (y - ((x * 0x1999999Al) >> 32)) * 10; //y * 10 + x - (x/10) * 10;
        x = ((x * 0x1999999Al) >> 32);
    }
    return y;
}

我还尝试使用bitshift操作(x * 10 = (x << 3) + (x << 1))将乘法乘以10,但它似乎并没有影响性能。 最高回答of this stackoverflow question显示了如何快速划分10个。为了完整性,提供的答案表明可以按照以下方式完成(归功于John Källén

int32_t div10(int32_t dividend) {
    int64_t invDivisor = 0x1999999A;
    return (int32_t) ((invDivisor * dividend) >> 32);
}

此方法仅允许反转整数(最多2^31 - 1)。结果很长,2^31 - 1 = 2147483647reverse(2147483647) = 7463847412 > 2^31 - 1。 在x上执行模10操作的快速方法是将其除以并乘以10,然后从x中减去该结果。

答案 1 :(得分:1)

    public int reverse(int x) {
        int result = 0;

        StringBuffer sb = new StringBuffer(0);
        sb.append(x);

        result = Integer.parseInt(sb.reverse().toString());


        return result;
    }

答案 2 :(得分:0)

您可以利用Java lambda表达式。您所要做的就是将数字转换为String,使用lambda将其反转,然后转换回int。此代码的一点变化可以允许反转任意数量的字符。这里:

public static int reversal(int x) {
      String tmp =  String.valueOf( x );
      String result = Pattern.compile(" +").splitAsStream( tmp ).map(word->new StringBuilder(word).reverse())
      .collect(Collectors.joining(" "));
      return Integer.parseInt( result );
}