通过使用回溯解决数独问题而出错

时间:2019-02-11 23:10:44

标签: c sudoku recursive-backtracking

我正在尝试通过回溯来实现(SolveSudoku)的代码。 但是我总是会出错。

我看了互联网上的许多解决方案,但是它们不同,这使我感到困惑。这就是为什么我在这里问。 我认为错误可能出在某个地方的is_safe函数中,因为其他人通过使用引用/取消引用(指针/地址)解决了这个问题。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define N 9
int ** create_puzzle()
{
    int i , j;
    int **my_puzzle;
    my_puzzle =(int**)malloc(sizeof(int*)*9);

    int my_array [N][N]={ 0,1,9,   0,0,2,   0,0,0,
                          4,7,0,   6,9,0,   0,0,1,
                          0,0,0,   4,0,0,   0,9,0,

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

                          0,5,0,   0,0,6,   0,0,0,
                          4,7,0,   0,2,8,   0,7,9,
                          0,0,0,   1,0,0,   8,6,0};
    for (i =0;i<N;i++)
    {

        my_puzzle[i]=(int **)malloc(sizeof(int *)*9);
        for(j=0;j<N;j++)
        {
            my_puzzle [i][j]=my_array[i][j];

        }
    }
    return my_puzzle;
}
void print_puzzle(int **puzzle)
{
    int r,c;

    for(r=0;r<N;r++)
    {
    if(r%3==0){
            printf("-------------------------------\n");
                   }
        for(c=0;c<N;c++)
        {
            if(c%3==0)
            printf("|");
            printf("%d  ",puzzle[r][c]);

        }
        printf("| \n");
    }
    printf("-------------------------------\n");
}

//function to check if all cells are assigned or not
bool is_zero(int **puzzle,int row ,int column)
{
    if(puzzle[row][column]==0)
    {
        return true;
    }
    return false;
}
//checking in row
bool check_Row(int **puzzle,int number,int column)
{
    for(int row=0;row<9;row++)
    {
        if(puzzle[row][column]==number)
        {
            return true;
        }

    }
     return false;
}
//checking column
bool check_Column(int ** puzzle,int number,int row)
{
    for(int column=0;column<9;column++)
    {
        if(puzzle[row][column]==number)
        {
            return true;
        }
    }
    return false;
}
//checking sub matrix
bool check_box(int **puzzle,int number,int row,int column)
{
    int row_start=(row/3)*3;
    int start_column=(column/3)*3;

    for(int i=row_start;i<row_start+3;i++)
    {
        for(int j=start_column;j<start_column+3;j++)
        {

    if(puzzle[i][j]==number)
    {
        return true;
    }
        }
    }
   return false;
}
//function to check if we can put a
//value in a paticular cell or not
bool is_safe(int ** puzzle,int number,int row,int column)
{
    if(is_zero(puzzle,row ,column))
    {
        return !check_Row(puzzle,number,column)&&
               !check_Column(puzzle,number,row)&&
               !check_box(puzzle,number, row,column);
    }
    return false;
}
//function to solve sudoku
//using backtracking
bool sudoko_solver(int **puzzle)
{
    int row,column;
    int number=0;
    for(row=0;row<9;row++)
    {
        for(column=0;column<9;column++)
        {
            if(is_safe(puzzle[row][column],number,row,column))
            {
                puzzle[row][column]=number;
                if(sudoko_solver(puzzle))
                {
                    return true;
                }
                else
                {
                    puzzle[row][column]=0;
                }
            }
        }
    }
 return false;
}
int main ()
{
    int **puzzle= create_puzzle();
    print_puzzle(puzzle);
    if(sudoko_solver(puzzle))
    {
        print_puzzle(puzzle);
    }
    else
    {
        printf("No solution");
    }
    return 0;
}

我总是得到-1073741819作为输出。

2 个答案:

答案 0 :(得分:1)

您两次添加了一个标题:

#include <stdlib.h>
#include <stdlib.h>

,省略了

#include <stdio.h>

即使得到纠正,也会有一些编译器警告,其中四个类似

  

警告C4715:“ check_Column”:并非所有控制路径都返回值

一个是

  

警告C4024:“ is_safe”:正式和实际的不同类型   参数1

,还有两个类似于

  

警告C4047:'=':'int *'在间接级别上与'int不同   **'

运行时我的编译没有给出错误的答案:它崩溃了。因此,请修复所有警告。

答案 1 :(得分:1)

功能

    bool check_Row(int **puzzle,int number,int column)
    {
        for(int row=0;row<9;row++)
        {
            if(puzzle[row][column]==number)
            {
                return true;
            }
            else{return false;}
        }
    }

仅测试第0行。无论那里有多少,它都会立即返回。同上其他检查。