数独 - 区域测试

时间:2011-07-23 11:54:16

标签: java sudoku

我正在使用'强力'随机方法创建一个数独生成器。我已经能够使用代码检查x / y轴上的重复数字:

for(l=0; l<9; l++){//Makes all vertical work.
                   if(sudoku[l][j] == temp){
                       isUsed=true;
                   }
                }                  
                for(m=0; m<9; m++){//makes all horizontal work
                   if(sudoku[i][m] == temp){
                       isUsed=true;
                   }
                }

我决定实施'box'或'region'检查(从原点检查每个3x3的方格),我似乎无法绕过代码。这是我到目前为止所做的。我只是无法弄清楚我的逻辑错误在哪里(对于记录程序将使用此代码运行,但不会正确检查区域)

rowbase = i-(i%3);
                if(i==2  || i==5 || i==8 ){
                    if(rowbase == 0 || rowbase == 3 || rowbase == 6){
                       isUsed= RegionCheck.RegCheck(rowbase, sudoku);
                    }
                }

regionCheck.java的内容:

       boolean okay = false;
    int[] regionUsed = new int[9];
    int i=0, j=0, regionTester=0, counter=0, numcount;
    for (i=regionTester; i<regionTester+3; i++){
        for (; j<3; j++){
           regionUsed[counter]=sudoku[i][j];
           counter++;
        }
    }
    for(i=0; i<9; i++){
        numcount=regionUsed[i];
        for(j=0; j<9; j++){
            if(j==i){
                //null
            }
            else if(numcount == regionUsed[j]){
                okay=false;
            }
        }
    }

    return okay;

在某个地方,我只是迷路而不理解如何“选择”一个区域并遍历区域。

完整来源:http://ideone.com/FYLwm

任何关于如何“选择”某个区域进行测试然后迭代它的帮助都会非常感激,因为我真的没有想法。

2 个答案:

答案 0 :(得分:1)

我无法理解测试某个地区的含义, 我假设测试意味着每个区域都有从1到9的每个数字而没有重复。

我们可以实施:

  1. 用于垂直,水平和3x3区域的循环。
  2. 使用对每个区域都有位置的表格,包括水平或垂直区域。
  3. 我的推荐是第二个。 如果您有一个表,则访问区域的循环将实现一次。 另一方面,第一个需要为垂直/水平/ 3x3实现3个类似的循环。

    以下是生成表格的代码:

    for(int i=0, k=0; i<9; i++) {
        // generate vertical regions
        for(int j=0; j<9; j++)
            table[k][j] = new table_t(i, j);
        k++;
        // generate horizontal regions
        for(int j=0; j<9; j++)
            table[k][j] = new table_t(j, i);
        k++;
        // generate 3x3 regions
        for(int j=0; j<9; j++)
            table[k][j] = new table_t((i/3)*3+j/3, (i%3)*3+j%3);
        k++;
    }
    

    生成垂直或水平区域的代码易于阅读。 虽然应该描述3x3区域生成。 变量i取自0到8,((i/3)*3(i%3)*3)分别指向3x3区域的角。并且(+j/3+j%3)移动该区域中的每个框。

    您可以通过以下代码测试矩阵sudoku是否合规:

    boolean okey = true;
    for(int i=0; i<27; i++) {
        int [] counter = new int[10];
        for(int j=0; i<10; i++)
            counter[i]=0;
        for(int j=0; j<9; j++)
            counter[ sudoku[table[i][j].x][table[i][j].y] ] ++;
        boolean ok = true;
        for(int j=0; j<9; j++)
            if(counter[j+1]!=1)
                ok = false;
        if(!ok)
            okey = false;
    }
    

    数组counter计算每个数字的出现次数 (我认为0是一些特殊含义,19之间的数字有效。)

答案 1 :(得分:1)

你需要抽象一点。可以这样想,任何区域(框,列,行)只是值列表(和空值)。要检查值x是否可以插入到区域R中,只需将R中的所有值表示为值L列表。现在,您只需检查L是否包含x

祝你好运!