java - 求 Recamán 数列的第 n 个值
问题描述
我的一个实验问题是编写一段代码来计算 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 的数字,几乎总是发生。
我似乎无法弄清楚我做错了什么,如果有人能指出我正确的方向,我将不胜感激。
解决方案
!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];
}
推荐阅读
- html - 使用引导网格,如何添加响应式图像并适合网格
- sql - 选择 * 其子项满足某些条件的父记录
- angularjs - 提交和数据清除后的AngularJS验证错误
- java - Java Lombok - 最佳实践?
- php - 来自用户表的 PHP Laravel Auth 密码,来自另一个表的 ID
- c# - 无法从另一个框架更新文本框,我该如何解决?
- c# - 如果我使用不可为空的引用类型,我如何证明我没有找到任何东西?
- azure - 使用 JSON 模板重置从映像部署的 Azure VM
- r - mutate_if、summarize_at 等强制 data.table 到 data.frame
- android - MaterialComponents Snackbar 在状态栏下方绘制,尽管我在其上定义了正确的边距