在数独中寻找零

时间:2011-03-07 19:16:29

标签: java arrays sudoku

我有一个课程作业(它已经过去了),我必须编写一个数独求解器。我能够创建一个可以解决每个缺失数字的方法。但是我在创建一个方法来找到我需要解决的细胞时遇到了麻烦。我应该采用2D数组并填写缺失的数字(由0表示)。 我已将下面的一些代码放在下面,但不是全部(尽管作业已经通过,我尊重教授的意愿)。

public class SolveSudoku {

    private static int[][] grid = new int[9][9];

    public static int[][] getSolution(int[][] grid) {
        for (int i = 0; i < 9; i++) {
            System.arraycopy(grid[i], 0, SolveSudoku.grid[i], 0, 9);
        }
        int n = getZero();
        return getSolution(n);
    }

    private static int[][] getSolution(int n) {
        if (n == 0) {
            return grid;
        }
        Cell cell = getZero();
        int row = cell.row;
        int column = cell.column;
        for (int number = 1; number <= 9; number++) {
            //checks cell using another method
            //I have booleans that return true if the number works
        }
        return null;
    }

    private static int getZero() {
        return 0;
    }

    private static class Cell {
        int cell = 0;
        int row = 0;
        int column = 0;
        int number;
    }
}

我有getZero方法,必须找到网格中的每个零(0表示缺少数字),所以我可以解决它。我应该如何在getZero中找到我需要替换的细胞?

3 个答案:

答案 0 :(得分:1)

您不会检查该号码是否在相同的3x3方格中重复(仅限行和列)。

我不明白“找零”是什么意思。实际上它没有意义,从第一行解决数独或最后一行在解决方案中没有效果。我将解释我为同样的麻烦做了什么。

  1. 单元格不是int,是对象。在对象中,我存储一个值(如果找到它,则为0,如果不存在,则为0)和布尔值[9]。假意(index + 1)被丢弃,因为它在同一行/列/方格中,true表示它尚未确定。此外,3个列表(矢量,集,等等)。
  2. 81个单元格的列表(如果您愿意,可以将其设为二维数组。)
  3. 9列表/向量/表示行的集合,9表示列,9表示正方形。将81个单元中的每一个分配给其行/列/方形。在每个单元格内部,您可以存储对其所属列表的引用。
  4. 现在是执行部分。在第一次迭代中,每当您找到非零(数字中固定的数字)时,您将遍历该单元所属的列表。对于这些列表中的每个单元格,将分配给该数字的布尔值标记为false。
  5. 循环遍历单元格,每次找到0时,您都会检查单元格中有多少布尔值是真的。如果它是1(所有其他8个可能的值都被丢弃),则它是单元格的值。你设置它,并在4)中获得它所属的列表,并在每个单元格中将该数字标记为false。循环直到你得到一个解决方案,或者你不能设置任何数字的迭代(没有直接可用的解决方案,必须以回溯或类似方式开始)。
  6. 记得在上键盘之前,要清楚地了解问题是什么以及如何在没有计算机的情况下解决问题。如果您不知道自己想做什么,计算机将无法提供帮助(除非您在stackoverflow中发布) -

答案 1 :(得分:0)

据我所知,你想找到grid中的第一个0值小区。我将首先定义为包含最低零行的第一个包含零的列。

这可以使用天真的搜索来完成:

private Cell getZeroCell(){
    int rz = -1;
    int cz = -1;
    outer: for(int row = 0; row < grid.length; row++){
        for(int col = 0; col < grid[row].length; col++){
            if(grid[row][col] == 0){
               rz = row;
               cz = col;
               break outer;
            }
        }
    }
    if(rz == -1 || cz == -1){
       // no zeros found
       return null;
    }else{
       // first zero found at row `rz` and column `cz`
       Cell cell = new Cell();
       cell.row = rz;
       cell.column = cz;
       return cell;
    }
}

获取包含零的第一个单元格的“数字”(从左到右计数,然后从上到下计数,0-索引):

private int getZeroInt(){
    int rz = -1;
    int cz = -1;
    outer: for(int row = 0; row < grid.length; row++){
        for(int col = 0; col < grid[row].length; col++){
            if(grid[row][col] == 0){
               rz = row;
               cz = col;
               break outer;
            }
        }
    }
    if(rz == -1 || cz == -1){
       // no zeros found
       return -1;
    }else{
       return rz * grid[0].length + cz;
    }
}

获取包含零的单元格数:

private int getNumZeros(){
    int count = 0;
    for(int row = 0; row < grid.length; row++){
        for(int col = 0; col < grid[row].length; col++){
            if(grid[row][col] == 0){
              count++;
            }
        }
    }
    return count;
}

答案 2 :(得分:-2)

由于评论中的长度限制,我将此作为答案发布。如果你想跳过所有的乐趣,并检查如何f。天才解决了这个问题,转到here

前段时间我尝试构建一个数独求解器来练习如何进行TDD。我发现表示问题的一个好的数据结构是有一个9x9网格的单元格对象(只是为了打印数字),然后是辅助数组,它们代表了列,行和区域,这样算法就可以解决了数独,只需要一个数组作为参数。

我发现的另一件事是Cell对象可以实现为“阴影数字”列表,那些是可以进入该单元格的数字。因此,当一个Cell在shado数组中只有一个数字时,它就会被解决。并且,例如,当一个数字被解决时,它将从相关行,列和区域中的所有单元格中删除。

我知道这不是一个真正有用的答案,但是对于一个无法通过“只是编码”解决的问题尝试TDD是一种很棒的体验。