简体   繁体   English

通过回溯解决数独-C ++

[英]solve sudoku with backtracking - C++

So I am trying to solve sudoku with backtracking 所以我试图通过回溯来解决数独

And with this example : example_pic 并带有以下示例: example_pic

I hard-coded some of the indexes in the two dimensional array with numbers on places given from webSudoku (picture above). 我将二维数组中的某些索引硬编码为从webSudoku(上图)给出的位置上的数字。 It definitely has solutions but, my code prints "solution doesn't exist 它肯定有解决方案,但我的代码显示“解决方案不存在

Here is my code : 这是我的代码:

#include <stdio.h>
int a[10][10]= {{2,0,0,0,9,0,0,3,1},
            {0,0,3,5,0,6,0,2,0},
            {0,0,8,1,3,0,5,4,0},
            {7,2,0,0,0,9,0,0,4},
            {4,0,0,0,0,0,0,0,8},
            {3,0,0,6,0,0,0,9,5},
            {0,7,6,0,4,5,1,0,0},
            {0,1,0,9,0,7,4,0,0},
            {5,3,0,0,8,0,0,0,6}};

bool is_valid(int x, int y, int value){
    if(a[x][y] != 0) return false;

    //check_row and column
    for(int tmp=1; tmp<=9; tmp++){
        if(value == a[x][tmp]) return false;
    }
    for(int tmp=1; tmp<=9; tmp++){
        if(value == a[tmp][y]) return false;
    }
    //check in 3*3 block
    int x_s = (x-1)/3*3 + 1;
    int y_s = 3*((y+2)/3-1)+1;
    for(int ch_x = x_s; ch_x<x_s+3; ch_x++){
        for(int ch_y=y_s; ch_y<y_s+3; ch_y++){
            if(ch_x!=x && ch_y!=y){
                if(value==a[ch_x][ch_y]) return false;
            }
        }
    }
    return true;
}

bool find(int &x, int &y){
    // check if valid cells are exists
    for(x=1; x<=9; x++){
        for(y=1; y<=9; y++){
            if(a[x][y] == 0)
                return true;
        }
    } 
    return false;
}

bool solve(){
    int x,y;
    //base::case
    if(!find(x,y)) return true;
    for(int cand = 1; cand <=9; cand++){
        if(is_valid(x,y,cand)){
            a[x][y] = cand;
            if(solve()) return true;
            a[x][y] = 0;
        }
    }
    return false;
}

void print(){
    //print the sudoku plate
    for(int i=1;i<=9; i++){
        for(int j=1; j<=9; j++){
            printf("%2d",a[i][j]);
        }
        printf("\n");
    }
    return ;
}

int main(){
    //Fill in some empty grid with the known values
    /*for(int i=1; i<=9; i++){
        for(int j=1; j<=9; j++){
        scanf("%1d",&a[i][j]);
        }
    }*/

    if (solve()) print();
    else printf("No solution exists\n");
    return 0;
}

I guess my 'solve function' or 'is_valid' function is not working right. 我猜我的“解决功能”或“ is_valid”功能无法正常工作。

In 'is_valid' function, if there is problem it would be 在“ is_valid”函数中,如果出现问题

bool find(int &x, int &y){
// check if valid cells are exists
    for(x=1; x<=9; x++){
        for(y=1; y<=9; y++){
            if(a[x][y] == 0)
                return true;
        }
    }
    return false;
} 

But, I also hard-coded this part and in my scope it doesn't seem like have problem. 但是,我也对该部分进行了硬编码,在我看来,这似乎没有问题。

In 'solve function' 在“解决功能”中

bool solve(){
    int x,y;
    //base::case
    if(!find(x,y)) return true;
    for(int cand = 1; cand <=9; cand++){
        if(is_valid(x,y,cand)){
            a[x][y] = cand;
            if(solve()) return true;
            a[x][y] = 0;
        }
    }
    return false;
}

I cant figure out where i got it wrong. 我不知道我在哪里弄错了。 If you find any other mistakes in the solve() function - let me know. 如果您在solve()函数中发现任何其他错误,请告诉我。 Because I am not sure I understand the "backtracking" thing completely... 因为我不确定我是否完全理解“回溯”的内容...

ps : reference I read ( https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf ) ps:我阅读过的参考资料( https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf

There are a few mistakes 有一些错误

  • You are mixing up (x, y) and (row, col) addressing (row is y, not x). 您正在混合(x, y)(row, col)寻址(行是y,而不是x)。 Choose a representation and stick to it 选择一个表示并坚持下去
  • There is a typo in is_valid because the check on (c, x) should be on (c, y) (or (y, c) depending on convention but surely using y and not x again) is_valid有一个错字,因为对(c, x)的检查应该在(c, y) (或(y, c)取决于约定,但是一定要使用y而不是再次使用x
  • The 3x3 sub-block computation is wrong... a correct formula could be for example int start_x = (x-1)/3*3 + 1, start_y = (y-1)/3*3 + 1; 3x3子块计算错误...正确的公式可能是例如int start_x = (x-1)/3*3 + 1, start_y = (y-1)/3*3 + 1;

Fixing all that the code works on the given example 修复所有代码可用于给定示例的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM