如何在数独子网格 (3x3) 中存储数字的出现次数?

How can I store the occurences of a number in a sudoku subgrid (3x3)?

所以我一直在尝试将所有从 1 到 9 的数字存储在一个数组中。我对行和列都成功了,并尝试对 3x3 的子网格应用相同的逻辑,但无济于事。

我的数独网格是一个 9x9 的二维数组(故意将两个 9 放在同一个子网格中以触发错误消息)。

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

这是我的函数代码:

int no_conflict_3x3(int sudoku[N][N]){
    int occurrence[N] = {0};
        for (int l=0; l<3;l++){
            for(int k = 0; k<3; k++){
                for (int i=0+3*k; i<3*k; i++){
                    for(int j=0+3*l; j<3*l; j++){
                    printf("%d", sudoku[i][j]);
                        switch(sudoku[i][j]){
                case 1:
                    occurrence[0]++;
                    break;
                case 2:
                    occurrence[1]++;
                    break;
                case 3:
                    occurrence[2]++;
                    break;
                case 4:
                    occurrence[3]++;
                    break;
                case 5:
                    occurrence[4]++;
                    break;
                case 6:
                    occurrence[5]++;
                    break;
                case 7:
                    occurrence[6]++;
                    break;
                case 8:
                    occurrence[7]++;
                    break;
                case 9:
                    occurrence[8]++;
                    break;
                default:
                    break;
                }
            }
        }
        
        for (int o = 0; o<N; o++){
                printf("o = %d : occurence=%d | ", o+1, occurrence[o]); //DEBUG
            if (occurrence[o]>1){
                printf("Not a valid sudoku grid.\n");
                return 1;}
            else occurrence[o] = 0;
            }
            printf("\n");
         
     }
     }
        
        return 0;
}

这是一次迭代后的结果(对于一行):

o = 1 : occurence=0 | o = 2 : occurence=0 | o = 3 : occurence=0 | o = 4 : occurence=0 | o = 5 : occurence=0 | o = 6 : occurence=0 | o = 7 : occurence=0 | o = 8 : occurence=0 | o = 9 : occurence=0 |
 

我不知道为什么我的变量出现次数停留在 0。有什么帮助吗?

你有 2 个被忽略的循环,因为你从头到尾循环。 你的 i 和 j 循环就像:

for (int i = 0; i < 0; ++i){...}

它什么都不做。

改变

for (int i=0+3*k; i<3*k; i++){
    for(int j=0+3*l; j<3*l; j++){

至:

for (int i=3*k; i<3*(k+1); i++){
    for(int j=3*l; j<3*(l+1); j++){

注意 i < 3*k 已更改为 i < 3*(k + 1),j

也类似

另一方面,你计算 'golbal occurence',但你需要在每个 3x3 子网格中使用它们...

  1. 我们需要为每个网格重置 occurrences[]

  2. 我们不需要计算一个数字的出现次数,如果它是重复的,那么我们就有一个无效的网格 (3x3)

  3. 我们不需要 switch 大小写,数字本身就是 occurrences[]

    的良好索引
#include <stdio.h>
#include <unistd.h>

#define N 9

int no_conflict_3x3 (int sudoku[N][N]) {
    // grids 3 x 3
    for (int gri = 1; gri < N; gri += 3) { // grid row id
        for (int gci = 1; gci < N; gci += 3) { // grid column id
            int occurrence[N +1] = {0}; // +1 to use  index [9]
            for (int ri = gri -1; ri <= (gri +1); ++ri) {
                for (int ci = gci -1; ci <= (gci +1); ++ci)
                    if (sudoku[ri][ci] && occurrence[sudoku[ri][ci]]) {
                        printf ("Invalid Grid, Grid Center [%d][%d].\n", gri, gci);
                        return 1;
                    } else
                        occurrence[sudoku[ri][ci]] = 1;
            }
            for (int gi = 1; gi <= N; ++gi)
                printf ("%d: occ %d | ", gi, occurrence[gi]);
            putchar ('\n');
        }
    }
    return 0;
}


int main (void) {
    int sudoku [N][N] = {
        {0, 1, 4, 0, 0, 0, 0, 1, 0},
        {9, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 0, 5, 4, 0, 9, 2, 0, 7},
        {0, 0, 0, 3, 9, 6, 0, 0, 0},
        {0, 8, 0, 0, 0, 0, 0, 2, 0},
        {0, 0, 0, 2, 7, 8, 0, 0, 0},
        {3, 0, 7, 8, 0, 2, 5, 0, 9},
        {1, 0, 0, 0, 0, 0, 0, 0, 3},
        {0, 4, 0, 0, 0, 0, 0, 6, 5}
    };
    int status = no_conflict_3x3(sudoku);

    return 0;
}