3

我开始了一个项目,试图创建一个 Ken Ken 拼图。如果您不确定 Ken Ken 是什么,它与 Sudoku 的相似之处在于行或列中不能有重复的整数值。

我正在尝试使用为每个新行创建的数组列表中的数字填充二维数组。我检查从数组列表中获取的数字是否与它自己的行和列中的任何数字不匹配。

当我运行我的代码时,当我尝试从列表中删除整数值时,我得到一个“索引超出范围”异常。我不确定为什么会发生这种情况,因为我认为我得到了正确的元素。

这是我的代码:

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 Array 更好的用于网格和放置数字的方式

最后,我是否正确使用了休息

提前感谢您的回答。

4

4 回答 4

2

发生这种情况是因为APIIndexOutOFBoundsException中的故障 (IMO) 。List它有一个remove(Object element)方法,即您要调用的方法,以及一个remove(int index)方法,即您实际调用的方法。后者尝试删除给定索引处的元素,因为您的参数可能大于列表大小,所以该索引不存在。您可以将ranNum变量转换为Integer或者Object确保调用正确的方法。

于 2012-07-29T22:25:59.490 回答
1
for (int i = 0; i <= GRID_SIZE; i++) nums.add(i);

这对我来说没有多大意义。您正在添加 0-4 的数字。您的数组中最多只有 3 个索引。0-1-2-3...

没有真正看到更多的代码,或者确切地知道你在哪里让你的索引越界......这是在黑暗中的一个镜头。

于 2012-07-29T22:28:05.283 回答
1

解决问题的不同方法怎么样?从一个有效的正方形开始并对其进行变换。“交换两行”和“交换两列”这两个操作保留了正方形的属性。这使您可以进行两次Fisher-Yates洗牌,一次在行上,一次在列上,只要您从有效的方格开始,这将为您提供一个有效的随机方格。构造一个初始的有效正方形很简单:

123456
234561
345612
456123
561234
612345
于 2012-07-30T14:45:34.990 回答
0

再次仔细查看我的代码后,我意识到我的主要错误与canPlace(int ranNum, int row, int col)方法有关。

我所做的只是交换colrow,它起作用了。

感谢大家的帮助。

于 2012-07-30T04:57:13.867 回答