Java:找到Collat​​z序列中最大的链

时间:2012-12-26 01:54:19

标签: java collatz

我找不到Project Euler问题#14的错误。我的第一步是找到算法,该算法一直有效,直到数字达到120000左右。代码断了,意识到我需要使用BigIntegers。我转换了我的算法以满足这种变化,但现在它不起作用。

我添加了System.out.print(chain_length)来帮助我处理代码可能会破坏的位置。

public static void main(String[] args) {
    BigInteger target = new BigInteger("1000000");
    BigInteger n = new BigInteger("0");

    final BigInteger zero = new BigInteger("0");
    final BigInteger one = new BigInteger("1");
    final BigInteger two = new BigInteger("2");
    final BigInteger three = new BigInteger("3");
    final BigInteger ten = new BigInteger("10");

    int greatest_index = 0;
    int greatest_length = 0;
    int chain_length = 0;

    BigInteger i = new BigInteger("2");
    for(i.equals(2) ; i.compareTo(target) == -1 ; i = i.add(one)) {
        n = i;
        chain_length = 1;
        while(n.compareTo(one) == -1) {
            chain_length++;
            if(n.mod(ten).equals(zero) == true){//even
                n = n.divide(two);
            }else{//odd
                n = n.multiply(three);
                n = n.add(one);
            }
            if(n.equals(one) == true && chain_length > greatest_length){
                greatest_length = chain_length;
                greatest_index = i.intValue();
            }
        }
        System.out.println(chain_length);
    }
    System.out.println(greatest_index);        
}

3 个答案:

答案 0 :(得分:7)

要测试数字是否均匀,您使用模2,而不是10.更改此行:

if(n.mod(ten).equals(zero) == true){//even

对此:

if(n.mod(two).equals(zero)) { //even

我还删除了不必要的== true

答案 1 :(得分:3)

除了@MarkByers的回答,

while(n.compareTo(one) == -1)

应该是

while(n.compareTo(one) > 0)

或者,在伪代码中,while n > 1

您还应该

if(n.equals(one) == true && chain_length > greatest_length){
    greatest_length = chain_length;
    greatest_index = i.intValue();
}

out of while循环,因为n永远不会在循环内等于one。 (并且由于在{while}循环后nalways(?)等于one,因此您可以完全摆脱第一个条件。)

最后,

中的i.equals(2)
for(i.equals(2) ; i.compareTo(target) == -1 ; i = i.add(one))

没有做任何有用的事情 - 它只是为大多数值返回false。

答案 2 :(得分:0)

正如Daniel Fischer所说,你应该使用很长时间。 小心不要做类似的事情 long a = 987654321
正确的版本(如果你想要长):long a = 987654321L
简单版本:

int maxChain = 0;
    int answer = 0;
    for (int i = 1_000_000; i > 0; i--) {
        int chain = 0;
        long n = i;
        while (n != 1) {
            if ((n & 1) != 1) { //Is even
                n = n / 2;
                chain++;
            } else { //Is odd
                n = 3 * n + 1;
                chain++;
            }
        }
        if (chain > maxChain) {
            maxChain = chain;
            answer = i;
        }
    }
    System.out.println(answer);
    System.out.println(maxChain);