求Recamán序列的第n个值

时间:2019-04-01 21:45:14

标签: java

我的实验室问题之一是写一段代码来计算Recamán序列的第n个值。

我给出的测试用例上升到Recamán序列的第100,000个值,确定该值本身的算法不是我的问题,我的问题是以一种不需要太多方式编写程序的问题长期运行。为了实现这一点,我的教授给了我们提示,建议使用大小为n * 10的足够大的Boolean [],并使用它来跟踪哪些整数值已属于所生成序列的一部分,而不是遍历整个先前生成的值

我有一些代码,我相信应该可以很好地解决这个问题,但是我遇到的问题是数组索引不足。通过我们提供的自动测试仪,它会随机询问1-100,000的第n个值。但是,在我的Boolean []中,我遇到了空间不足的问题,以检查数字是否已生成。

我的代码如下

   public static int recaman(int n){
        int[] seq = new int[n];
        boolean[] check = new boolean[10 * n]; 

        seq[0]=0;
        check[0]=true;
        for(int k=1;k<=n;k++){
            int minusVal = seq[k-1]-k;
            int plusVal = seq[k-1] + k;
            if((minusVal>0)&&(!check[seq[minusVal]])){
                seq[k]= minusVal;
                check[minusVal] = true;
            }else{
                seq[k] = plusVal;
                check[plusVal]=true;
            }
        }
        return seq[n];
   }

并运行recaman(100)会导致以下错误

  

Java.lang.ArrayIndexOutOfBoundsException:104
  在   P2J2.recaman(P2J2.java:78)

奇怪的是,对于小数字来说,错误并非每次都会出现,而对于〜400以上的任何数字,几乎都会一直发生。

我似乎无法弄清楚我在做错什么,如果有人可以指出正确的方向,我将非常感激。

2 个答案:

答案 0 :(得分:2)

!check [minusVal]是正确的方法。

public static int recaman(int n)
        {
            int[] seq = new int[n];
            boolean[] check = new boolean[10 * n];

            seq[0] = 0;
            check[0] = true;
            for (int k = 1; k < n; k++)
            {
                int minusVal = seq[k - 1] - k;
                int plusVal = seq[k - 1] + k;
                if ((minusVal > 0) && (!check[minusVal]))
                {
                    seq[k] = minusVal;
                    check[minusVal] = true;
                } else
                {
                    seq[k] = plusVal;
                    check[plusVal] = true;
                }
            }
            return seq[n - 1];
        }

答案 1 :(得分:1)

对于k=16 minusVal = 104,您检查!check[seq[minusVal]]。这就是错误的原因。似乎您也需要制作int[] seq = new int[n * 10];。希望能帮助到你!

PS。我用int[] seq = new int[n * 10];测试了它,但仍然有同样的错误。通常,条件!check[seq[minusVal]]是错误的,并且可能导致错误的结果。您应将其替换为!check[minusVal],因为您想检查以前是否存在MinusVal,而不是seq[minusVal]

这段代码对我来说没有错误:

public class HelloWorld {

    public static int recaman(int n){
        int[] seq = new int[n * 10];
        boolean[] check = new boolean[10 * n]; 

        seq[0]=0;
        check[0]=true;
        for(int k=1;k<=n;k++){
            int minusVal = seq[k-1]-k;
            int plusVal = seq[k-1] + k;
            if((minusVal>0)&&(!check[minusVal])){
                seq[k]= minusVal;
                check[minusVal] = true;
            }else{
                seq[k] = plusVal;
                check[plusVal]=true;
            }
        }
        return seq[n];
   }


    public static void main(String[] args) {
        System.out.println("Hello World!");
        recaman(100000);
    }
}