2012-07-29 260 views
3

我已经开始一个项目,试图创建一个Ken Ken难题。如果你不确定Ken Ken是什么,它就像Sudoku一样,在行或列中不能有重复的整数值。用随机数字填充二维数组

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

当我运行我的代码时,当我尝试从列表中删除整数值时,出现“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; 
} 

我有这几个问题:

首先,为什么我得到错误我是

其次还有什么更好的比一个二维数组,网格和我把我的号码方式使用?

最后,上午我正在使用中断

在此先感谢您的答案。

+0

这似乎错在第二个for循环:'我<= GRID_SIZE'您正在使用什么确切的数据类型来存储随机数一览表 – Keppil 2012-07-29 22:21:58

+0

?如果它是一个列表,那么当你删除东西时它可能会缩小,所以如果你的列表有9个,并且你找到一个并删除它,那么它现在有8个。如果你再次查看第9个位置,这是一个超出界限例外 – 2012-07-29 22:22:42

+0

我真的不知道从哪里开始。即使小问题得到解决,您的整个方法似乎都是错误的,并且无法解决最棘手的问题。你需要回溯。 – 2012-07-29 22:22:54

回答

1

如何解决问题的不同方法?从一个有效的方块开始并转换它。两个操作“交换两行”和“交换两列”保留了广场的属性。这可以让你做两个Fisher-Yates洗牌,一个在行上,一个在列上,只要你从一个有效的方块开始,它就会给你一个有效的随机方块。构建初始有效方很简单:

123456 
234561 
345612 
456123 
561234 
612345 
+0

非常感谢你,我尝试了这个想法,并且已经完成了它(与许多其他益智游戏一起)。谢谢! – 2012-08-21 08:02:27

2

IndexOutOFBoundsException是因为List API中的故障(IMO)而发生的。它有一个remove(Object element)方法,这就是你想要调用的方法,和一个remove(int index)方法,这就是你实际调用的方法。后者试图删除给定索引处的元素,这不在那里,因为您的参数可能大于列表大小。 您可以将ranNum变量转换为IntegerObject以确保您调用正确的方法。

+0

非常感谢你的回答,我一直认为int和Integer是一样的,这是我学到的一个很好的教训。我现在已经修复了我的代码,现在它正在正常工作,再次感谢! – 2012-07-30 04:33:30

1
for (int i = 0; i <= GRID_SIZE; i++) nums.add(i); 

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

没有真正看到更多的代码,或确切地知道你在哪里得到你的索引越界...这是在黑暗中拍摄。

+0

感谢您的回复,我现在纠正了它,并且获得了我想要的数字。 – 2012-07-30 04:31:49

+0

@Jordan King如果答案是正确的,你应该接受它作为正确的答案,以便让人们知道什么是错的。很高兴帮助。 – 2012-08-01 21:52:29

0

在给我的代码再看一遍之后,我意识到我的主要错误是与canPlace(int ranNum, int row, int col)方法有关。

我所做的只是交换colrow它的工作。

感谢大家的帮助。