【问题标题】:checking validity of Sudoku Board. C program检查数独板的有效性。 C程序
【发布时间】:2021-05-09 18:20:21
【问题描述】:

我目前正在创建一个项目来检查给定的 9x9 数独表是否遵循数独规则。该表存储在一个多维数组(board[9][9])中,我被困在如何正确检查每个 3x3 子网格中是否存在重复数字。我已经对 0(空白)和 9(最大值)之外的数字进行了检查,并检查了每一行和每一列中的重复项。我已经管理了两个创建 4 个嵌套的 for 循环,它们成功地循环通过每个 3x3 框,但我不确定如何检查框中的值是否存在重复项。我对重复的定义是两个包含相同数字的单元格(除了在我的程序中保留为空白的零)。以下是我到目前为止的代码。此代码检查每个 3x3 子网格的第一列中的每个数字是否有效,但无法检查每个框的其他 2 列。

for(int x=0;x<9;x=x+3){                 //iterates through each 3x3 sub box going through each row. Temp B compares each value to all other values in box.
    for(y=0;y<9;y=y+3){
        for(j=x;j<x+3;j++){
            tempB = board[j][k];
                for(k=y;k<y+3;k++) {
                    for (z = x; z < x + 3; z++) {
                        if (z != j && tempB == board[z][k] && tempB != 0) {
                            return 0;
                        }
                    }
                }
        }
    }
}

【问题讨论】:

  • 是什么让您无法将行和列的方法调整到框?
  • 如何使用 9 大小的数组并计算使用数字 (-1) 作为索引访问的条目中每个可能数字的数量。如果你没有得到 0 或 > 1,你就很好。

标签: c for-loop multidimensional-array sudoku


【解决方案1】:

为什么从来没有人提供MCVE

正如 Yunnosch 建议的那样,您可以只计算数组中数字的出现次数。记得跳过空单元格 (0)。

#include <stdio.h>

int board_noduplicates(int board[9][9]) 
{
    for (int x = 0; x < 9; x += 3) {
        for(int y = 0; y < 9; y += 3) {
            int count[10] = { 0 };
            for(int j = x; j < x + 3; ++j) {
                for(int k = y; k < y + 3; ++k) {
                    int cur = board[j][k];
                    if(cur > 0 && count[cur] > 0) {
                        return 0;
                    }
                    ++count[cur];
                }
            }
        }
    }
    return 1;
}

int main(void) 
{
    int board1[9][9] = {
        {1,2,3, 0,0,0, 4,5,6,},
        {0,0,0, 1,0,0, 0,0,0,},
        {0,0,0, 0,0,8, 0,0,0,},

        {4,5,6, 2,0,0, 7,8,9,},
        {0,0,0, 0,1,0, 0,0,0,},
        {0,0,0, 0,0,3, 0,0,0,},

        {7,8,9, 4,0,0, 1,2,3,},
        {0,0,0, 0,5,0, 0,0,0,},
        {0,0,0, 0,0,6, 0,0,0,},
    };
    int board2[9][9] = {
        {1,2,3, 0,0,0, 4,5,6,},
        {0,0,0, 1,0,0, 0,0,0,},
        {0,0,0, 0,0,8, 0,0,0,},

        {4,5,6, 2,0,0, 7,8,9,},
        {0,0,0, 0,1,0, 0,0,0,},
        {0,0,5, 0,0,3, 0,0,0,}, // <-- duplicate

        {7,8,9, 4,0,0, 1,2,3,},
        {0,0,0, 0,5,0, 0,0,0,},
        {0,0,0, 0,0,6, 0,0,0,},
    };  
    
    printf("board_noduplicates(board1) -> %d\n", board_noduplicates(board1));
    printf("board_noduplicates(board2) -> %d\n", board_noduplicates(board2));
    
    return 0;
}

【讨论】:

  • 您也可以将当前子网格的元素存储到单个 int 中,而不是 10 个 ints 的数组中,前提是我们知道元素的最小值为 1,最大值为 9。
  • @frumle 是的,但为什么呢?以后会不会更难阅读?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-07
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多