我已经开始了一个项目,试图创建一个Ken Ken谜题。如果你不确定Ken Ken是什么,它与数独类似,在一行或一列中不能有重复的整数值。
我正在尝试用为每一新行创建的数组列表中的数字填充2D数组。我会检查从数组列表中提取的数字是否与它自己的行和列中的任何数字都不匹配。
当我运行代码时,当我尝试从列表中删除整数值时,我会得到一个"Index Out Of Bounds"异常。我不知道为什么会发生这种情况,因为我认为我得到了正确的元素。
这是我的代码:
int GRID_SIZE = 4;
int[][] grid = new int[GRID_SIZE][GRID_SIZE];
List<Integer> nums = new ArrayList<Integer>();
private void populateGrid() {
for (int row = 0; row < GRID_SIZE; row ++) {
// Creates an array of values from 1 to grid size.
for (int i = 1; i <= GRID_SIZE; i++) nums.add(i);
for (int col = 0; col < GRID_SIZE; col++) {
while (nums.size() > 0) {
// Gets a random number from the Array List
int ranNum = nums.get(numGen.nextInt(GRID_SIZE));
// Checks to see if the number is placeable.
if (canPlace(ranNum, row, col)) {
// Places the number in the 2D Array
grid[row][col] = ranNum;
break;
} else {
// Removes duplicate element from the Array List.
nums.remove(ranNum); <------{Index Out Of Bounds Exception]
}
}
}
}
}
private boolean canPlace(int ranNum, int row, int col) {
for (int i = 0; i < GRID_SIZE; i++) {
// Checks if the specified number is already in the row/column.
if (grid[col][i] == ranNum) return false;
if (grid[i][row] == ranNum) return false;
}
return true;
}
我对此有几个问题:
首先,为什么我会得到我是的错误?
其次还有什么比2D阵列更好的网格和我放置数字的方式吗?
最后,我是否正确使用了break?
提前感谢您的回答。
IndexOutOFBoundsException
发生是因为List
API中出现故障(IMO)。它有一个remove(Object element)
方法,这是您想要调用的,还有一个remove(int index)
方法,这就是您实际调用的。后者试图删除给定索引处的元素,因为您的参数可能大于列表大小,所以不存在该索引。您可以将ranNum
变量强制转换为Integer
或Object
,以确保调用的方法正确。
用不同的方法来解决这个问题怎么样?从一个有效的正方形开始并对其进行转换。"交换两行"one_answers"交换两列"这两个操作保留了正方形的属性。这允许你做两次Fisher-Yates洗牌,一次在行上,一个在列上,只要你从一个有效的正方形开始,就会得到一个有效随机正方形。构造一个初始有效平方是微不足道的:
123456
234561
345612
456123
561234
612345
for (int i = 0; i <= GRID_SIZE; i++) nums.add(i);
这对我来说没有多大意义。你在加0-4的数字。数组中最多只能有3个索引。0-1-2-3…
在没有实际看到更多代码的情况下,或者不知道索引超出范围的确切位置。。。这是在黑暗中拍摄的。
再次仔细查看代码后,我意识到我的主要错误与canPlace(int ranNum, int row, int col)
方法有关。
我所做的只是交换col
和row
的值,它起到了作用。
谢谢大家的帮助。