Java 中的冰雹序列与 ArrayList

Hailstone Sequence in Java with ArrayList

您好,我正在尝试执行冰雹序列。
冰雹序列基本上是:取一个给定的整数 n - 如果是偶数,序列中的下一个整数是 n/2,如果是奇数,序列中的下一个整数是 n * 3 + 1.
API 我必须遵循我的任务要求它像返回 arraylist 的方法一样执行。
我的问题是代码永远挂起,当我在方法本身中添加输出以查看发生了什么时,我看到它总是因为某种原因被赋予数字 10 时挂起。
我希望也许在我的条件下我在这里缺少一些小东西。

这是给定 n 值为 15 时的一些示例输出,它一遍又一遍地输出。

15 是奇数所以我把它变成 3n+1: 46
46 是偶所以我除以 2: 23
23 是奇数所以我把它变成 3n+1: 70
70 是偶所以我除以 2: 35
35 是奇数所以我把它变成 3n+1: 106
106 是偶所以我除以 2: 53
53 是奇数所以我把它变成 3n+1: 160
160是偶所以我除以2: 80
80 是偶所以我除以 2: 40
40 是偶所以我除以 2: 20
20 是偶数所以我除以 2: 10
15 是奇数所以我把它变成 3n+1: 46

我的代码

import java.util.ArrayList;
import java.util.Scanner;

public class HailstoneSequence {
    public static ArrayList<Integer> getHailstoneSequence(int n){
        ArrayList<Integer> results;
        results = new ArrayList<Integer>();
        results.add(n);

        //while the last number is not 1 perform these actions
        while((results.size() - 1) != 1){
            //for each number in the array
        for(int i=0; i< results.get(i); i++){
            //test if odd or even
            if((results.get(i)%2)==0){
                System.out.println(results.get(i)+" is even so I divide by 2: "+ (results.get(i)/2));

                   results.add((results.get(i)/2));

                   }
                else{
                    //odd
                    System.out.println(results.get(i)+" is odd so I make it 3n+1: "+ (3*(results.get(i))+1));
                    results.add((3*(results.get(i))+1));
                }

        }
        }
        return results;
    }

    public static void main(String[] args) {
        int n=0;
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the value of n ");
        n=sc.nextInt();
        sc.close();

        //create an initialize new array list to hold results of the hailstonesequence
        ArrayList<Integer> list;
        list = new ArrayList<Integer>();

       list = getHailstoneSequence(n);

        //for each number in the array
       for(int i=0; i< list.get(i); i++){

           if ((list.get(i)!= 1)){
            if((list.get(i)%2)==0){
                    System.out.println(list.get(i)+" is even so I divide by 2: "+ (list.get(i+1)));

                   }
                else{
                    //odd
                    System.out.println(list.get(i)+" is odd so I make it 3n+1: "+ (list.get(i+1)));

                }
           }
           else{break;}
        }

    }

    }

在您的方法 for(int i=0; i< results.get(i); i++){ 和主要 for(int i=0; i< list.get(i); i++){

这些不会遍历列表的每个元素,或者至少不止一次,如果您从未添加到列表中,它最终会导致越界。

假设 results.get(i) 是 10,这是列表中唯一的数字...然后您将 5 加十次,因为 10 是偶数并且循环是 运行 十次。然后你可能会添加 16 次 5*10 次,等等

在遍历列表时向列表添加元素通常不是一个好主意。您一次只需要跟踪两个数字,并且可以独立于迭代过程添加到列表中。


这是一个working sample

ArrayList<Integer> results = new ArrayList<Integer>();
results.add(n);
if (n == 1) return results;

int next;
if (n % 2 == 0) next = n / 2;
else next = 3*n + 1; 
results.add(next);

while (next != 1) {
    if (next % 2 == 0) next = next / 2;
    else next = 3*next + 1; 
    results.add(next);
} 
return results;