【问题标题】:Can someone tell me why I get this output?有人能告诉我为什么我得到这个输出吗?
【发布时间】:2013-04-21 18:45:48
【问题描述】:

好的,所以我有一个由以下代码定义的 Collat​​z 序列长度:

    private static int count = 0;

    private static int collatz(int n){
        count++;
        if(n > 1){
            if(n % 2 == 0){
                return collatz(n/2);
            }
            return collatz(3*n+1);
        }
        return count-1;
    }

现在,我检查了不同数字的输出(例如 print(collat​​z(3000)) => 48),以验证算法是否正常工作。我使用various sites 来执行此操作,但一个号码拒绝工作。而这个数字正是 ProjectEuler 第 14 个问题的解。这怎么可能,每隔一个数字我都会得到正确的结果(正确的链长度),而 837799 会产生不同的结果:58,而不是 524。

【问题讨论】:

  • 只是一个猜测:也许这个数字被选择得非常特别,因为它生成的序列包含大量溢出 Java int?
  • 你试过用 long 吗?
  • Mat 说得对,用long 看看。
  • @Eng.Fouad - 整数运算在这里很好。除以 2 仅适用于偶数。
  • 马特和子瑶是对的。我跟踪了整个程序,发现数字太大,int 无法处理。将所有内容更改为long,然后重试。

标签: java algorithm math collatz


【解决方案1】:

正如其他在 cmets 中指出的那样,这是一个溢出问题。您可以通过打印函数调用的参数来发现这一点。

int 更改为long,甚至更好,以确保它不会溢出,请使用BigInteger

private static int collatz(BigInteger n) {
    count++;
    if (n.compareTo(BigInteger.ONE) > 0) {
        if (!n.testBit(0)) // even
            return collatz(n.divide(BigInteger.valueOf(2)));

        else
            return collatz(n.multiply(BigInteger.valueOf(3)).add(BigInteger.ONE));
    }
    return count - 1;
}

public static void main(String[] args) {
    System.out.println("res: " + collatz(BigInteger.valueOf(837799)));
}

【讨论】:

    猜你喜欢
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2022-10-16
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多