冰雹序列,递归,缺少1个案例

时间:2018-12-07 16:41:17

标签: java recursion sequence collatz

我有以下冰雹序列代码,它适用于除1的序列之外的所有数字:

public class Recursion {
    public static void main(String[] args) {
        hailstone(16);  // prints  16 8 4 2 1
        hailstone(1);  //prints just 1 instead of 1 4 2 1
    }

    public static void hailstone(int seed) {
        String str = "" + seed;

        if (seed == 1) {
            System.out.print(str);
        } else {
            if (seed % 2 == 0) {
                System.out.print(str + " ");
                hailstone(seed / 2);
            } else {
                System.out.print(str + " ");
                hailstone((3 * seed) + 1);
            }
        }
    }
}

在停留在递归方法和空白中时,如何绕过这种特殊情况?

不允许使用任何循环。

2 个答案:

答案 0 :(得分:2)

1是递归的退出点,这就是为什么不能使它也像入口点一样起作用的原因。
如果更改出口点怎么办?将2设为出发点:

public static void hailstone(int seed) {
    String str = "" + seed;

    if (seed == 2) {
        System.out.print(str + " 1");
    } else {
        if (seed % 2 == 0) {
            System.out.print(str + " ");
            hailstone(seed / 2);
        } else {
            System.out.print(str + " ");
            hailstone((3 * seed) + 1);
        }
    }
}

public static void main(String[] args) {
    hailstone(16);
    System.out.println();
    hailstone(15);
    System.out.println();
    hailstone(1);
    System.out.println();
}

将打印:

16 8 4 2 1
15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
1 4 2 1

答案 1 :(得分:1)

最后,请您注意一下(我很惊讶看到代码中的所有静态内容)。

要点。你说:

  • 您不能更改签名
  • 您必须使用递归(不允许循环)

定义一个静态布尔值,并为达到数字1的情况添加条件。
冰雹序列中的最后一个序列是无限模式。特殊情况是因为您需要程序在某个时刻停止。在这里,我只使用布尔值就可以在第一次到达数字1之后打印一次图案。我希望代码能自我解释。

public class Recursion {

    private static boolean reached = false; 

    public static void main(String[] args) {
        //hailstone(16);  // prints  16 8 4 2 1
        hailstone(1);  //prints just 1 instead of 1 4 2 1
    }

    public static void hailstone(int seed) {
        String str = "" + seed;

        if (seed == 1 && reached) {
            System.out.print(str);
        } else if (seed == 1 && !reached) {
            System.out.print(str + " ");
            reached = true;
            hailstone((3 * seed) + 1);
        } else {
            if (seed % 2 == 0) {
                System.out.print(str + " ");
                hailstone(seed / 2);
            } else {
                System.out.print(str + " ");
                hailstone((3 * seed) + 1);
            }
        }
    }
}

注意:在Java中,通常不宜编写大量静态成员/方法。我相信可以设计得更好。我不想进入这个问题,因为我不想混淆,我想集中讨论这个问题。
例如,以我的方式进行编码存在一个缺点。只需尝试随后致电hailstone(16)hailstone(1),您就会明白我的意思;这是因为已经从第一个序列计算中设置了布尔值。您将需要再次将其重置为false。有更好的方法来设计这个...