Java中的Hailstone程序

时间:2015-12-04 16:17:44

标签: java loops if-statement for-loop methods

我有以下程序要写:

  

数学中一个有趣(但尚未解决)的问题被称为“冰雹数字”。这个系列是通过取一个初始整数产生的,如果数是偶数,则除以2.如果数是奇数,则将它乘以3并加1.这个过程是重复的。   

  例如:初始数字10产生:10,5,16,8,4,2,1,4,2,1 ......初始值23产生:23,70, 35,106,53,160,80,40,20,10,5,16,8,4,2,1,4,2,1 ......

     

请注意,这两个数字最终都会达到4,2,1,4,2,1 ......周期。

     

创建一个应用程序,为用户提供三种运行此程序的方法。   

  • 选项1 :打印单个条目的底线编号及其长度
      示例:输入> 10 10,5,16,8,4,2,1长度7   
  • 选项2 :将所有的冰雹数字从4打印到指定的条目
      示例:输入> 6 4,2,1长度3 5,16,8,4,2,1长度6 6,3,10,5,16,8,4,2,1长度9   
  • 选项3 :打印出需要达到循环的最大迭代次数的数字,以及从4到输入数字的最大起始数。   示例:输入> 6最长:6长度:9

         

    在编写此程序时,您必须实现以下方法......

  • /** 
     * 
     * @param num  Number that a hailstone chain will be generated 
     * @param showNumbers  true if list of numbers is shown to screen 
     * @return  Count of the numbers in the num hailstone chain.
     */
    private static int hailStone(int num, boolean showNumbers) {
        // your code
    }
    

    这是我到目前为止编写的代码:

    public static void main(String[] args) {
            int a = getInt("Give a number: ");
    
            System.out.print("How would you like to run the program? Option 1 prints hailstone numbers for a single entry and its length." +
                    "Option 2 prints all the hailstone numbers from 4 to a given entry. Option 3 prints the number with the maximum number" +
                    "of iterations needed to reach the 4, 2, 1 cycle.");
            int option = console.nextInt();
    
            boolean showNumbers = (option == 1 || option == 2);
    
            hailStone(a, showNumbers);
        }
    
        public static int getInt(String prompt) {
            int input;
    
            System.out.print(prompt);
            input = console.nextInt();
    
            return input;
        }
    
        private static void hailStone (int a, boolean showNumbers) {
            if (showNumbers == true) {
                if (a % 2 == 0) {
                    for (int i = 0; i < 50; i++) {
                       for (int j = 0; j <= i; j++)
                        a /= 2;
                        System.out.print(a + " ");
                        a *= 3;
                        a += 1;
                        System.out.print(a + " ");
                    }
    
                } else {
                    for (int i = 0; i != a; i++) {
    
                    }
                }
            } else {
    
            }
        }
    

    我觉得自己已经碰壁了,因为我不知道如何在我的老师要求我们使用的方法中实现所有这些选项。另外,我似乎无法打印基本的冰雹链。帮助

    2 个答案:

    答案 0 :(得分:1)

    HailStone算法不应该难以实现。如果你把它作为一个递归函数实际上会容易得多,因为这更自然地把它写成一个迭代函数可能是导致你的问题的原因。

    这应该足以让你入门,这是一个使用递归函数的HailStone实现。一旦你的算法正常工作,你就可以很容易地实现其余的项目需求......但是我想挑战你,一旦你得到正确的功能并将单元测试编写成一个函数,就把它转换成一个有效的迭代函数。测试程序。 (TDD规定你应该在编写实际实现之前编写测试。这是一个很好的做法,由于时间限制和强大的测试套件过度使用而经常被忽略。)

    HailStone.java

    public class HailStone {
        /* static variable to count calls to hailStone */
        public static int iterCount = 0;
    
        /* This variable is a senti */
        public static boolean isRepeating = 0;
    
        /* Simple main function */
        public static void main(String[] args) {
            // TODO:
            //   Either parse args or use a scanner to get input.
            //   Args = verbose, entryPoint
            hailStone(10, true);
        }
    
        /* Recursive hailStone implementation */
        private static void hailStone(int a, boolean showNumbers) {
            // start off by printing the numbers if showNumbers is true
            if (showNumbers) {
                System.out.printf("Iteration #%d: %d\n", ++iterCount, a);
            }
    
            // base case: a = 1 => most important part of recursion
            if (a == 1) {
                if (isRepeating) {
                    return;
                }
                isRepeating = true;
            }
    
            // check if a is odd
            // You can use modulo divison, but we'll use bitwise &
            /* Explained: [ bitwise AND... bits that are set in a AND in 1 ]
            **********************************************
                 Case 1: a is even =>
                     a = 10
                     10 in binary is 00001010
                      1 in binary is 00000001
                ------------------------------
                 10 & 1 in binary is 00000000
    
                 Case 2: a is odd =>
                     a = 10
                     11 in binary is 00001011
                      1 in binary is 00000001
                ------------------------------
                 11 & 1 in binary is 00000001
            **********************************************
                set(X) = set of all even numbers
                set(Y) = set of all odd numbers
                {
                  x is any arbitrary number in set X,
                  y is any arbitrary number in set Y
                }
                x & 1 will ALWAYS equal 0 -\
                                            >- know this. bitwise hacks rock.
                y & 1 will ALWAYS equal 1 -/
            */
            if ((a & 1) == 1) {
                a *= 3;
                a += 1;
            } else {
                a /= 2;
            }
    
            // Tail recursion.
            hailStone(a, showNumbers);
            return;
        }
    }
    

    没有所有评论和额外的东西:

    public class HailStone {
        public static int iter_count = 0;
        public static void main(String[] args) {
            hailStone(10, true);
        }
        /* Recursive hailStone implementation */
        private static void hailStone(int a, boolean showNumbers) {
            if (showNumbers) {
                System.out.printf("Iteration #%d: %d\n", ++iter_count, a);
            }
            // base case: a = 1
            if (a == 1) {
                return;
            }
            if ((a & 1) == 1) { // a is odd:
                a *= 3;
                a += 1;
            } else {
                a /= 2;
            }
            hailStone(a, showNumbers);
            return;
        }
    }
    

    答案 1 :(得分:0)

    private static Scanner console = new Scanner(System.in);
    
    public static void main(String[] args) {
        System.out.println("How would you like to run the program?");
        System.out.println(" [1] - print hailstone numbers for a single entry and its length.");
        System.out.println(" [2] - print all hailstone numbers from 4 to a given entry.");
        System.out.println(" [3] - print the number with the maximum number of iterations needed to reach the 4, 2, 1 cycle.");
        int option = queryInt("Option: ", 1, 3);
        switch (option) {
            case 1: {
                int seed = queryInt("INPUT> ", 1, Integer.MAX_VALUE);
                hailStone(seed, true);
                break;
            }
            case 2: {
                int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
                for (int i = 4; i <= maxSeed; i++) {
                    hailStone(i, true);
                }
                break;
            }
            case 3: {
                int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
                int longestChain = 0;
                int longestChainLength = 0;
                for (int i = 4; i <= maxSeed; i++) {
                    int length = hailStone(i, false);
                    if(length > longestChainLength) {
                        longestChain = i;
                        longestChainLength = length;
                    }
                }
                System.out.println("Longest: " + longestChain + " Length: " + longestChainLength);
                break;
            }
        }
    }
    
    private static int queryInt(String prompt, int min, int max) {
        while (true) {
            System.out.print(prompt);
            String input = console.nextLine();
            try {
                int result = Integer.parseInt(input);
                if (result >= min && result <= max) {
                    return result;
                } else {
                    System.err.print("Expected a number ");
                    if (min == Integer.MIN_VALUE) {
                        System.err.println(" less than or equal to " + max);
                    } else if (max == Integer.MAX_VALUE) {
                        System.err.println(" greater than or equal to " + min);
                    } else {
                        System.err.println(" between " + min + " and " + max);
                    }
                }
            } catch (NumberFormatException ex) {
                System.err.println("Not a number: " + input);
            }
        }
    }
    
    private static int hailStone(int num, boolean showNumbers) {
        int result = 1;
        for (Iterator<Integer> chain = iterateHailStone(num); num != 1; num = chain.next(), result++) {
            if (showNumbers) {
                System.out.print(num + ", ");
            }
        }
        if (showNumbers) {
            System.out.print(num);
            System.out.println(" (length=" + result + ")");
        }
        return result;
    }
    
    private static Iterator<Integer> iterateHailStone(int seed) {
        return new Iterator<Integer>() {
            int value = seed;
    
            @Override
            public boolean hasNext() {
                return true;
            }
    
            @Override
            public Integer next() {
                if (value % 2 == 0) {
                    value /= 2;
                } else {
                    value *= 3;
                    value++;
                }
                return value;
            }
        };
    }