数独bactracking需要帮助

时间:2017-03-22 16:50:50

标签: c++

我目前正致力于使用回溯来解决数独的数独求解器。我差点儿完成但它崩溃了,我不知道为什么,我试着在这里搜索与数据回溯有关的问题,但没有太多的光线,只要我可以缩小问题,我知道它在我的solveBoard函数但是仍然不确定,我也尝试搜索不同的网站,并得到一些帮助,但还不够。任何帮助?提前谢谢

#include <iostream>
using namespace std;

bool findBlankLocation(int board[9][9], int&, int&);
bool inColumn(int [9][9], int, int);
bool inRow(int [9][9], int, int);
bool inBox(int [9][9], int, int, int);
bool blankLocation(int[9][9], int, int, int);
void printBoard(int [9][9]);
bool solveBoard(int [9][9]);

int main()
{
    int board[9][9] =  {{3, 0, 6, 5, 0, 8, 4, 0, 0},
                        {5, 2, 0, 0, 0, 0, 0, 0, 0},
                        {0, 8, 7, 0, 0, 0, 0, 3, 1},
                        {0, 0, 3, 0, 1, 0, 0, 8, 0},
                        {9, 0, 0, 8, 6, 3, 0, 0, 5},
                        {0, 5, 0, 0, 9, 0, 6, 0, 0},
                        {1, 3, 0, 0, 0, 0, 2, 5, 0},
                        {0, 0, 0, 0, 0, 0, 0, 7, 4},
                        {0, 0, 5, 2, 0, 6, 3, 0, 0}};



    if(solveBoard(board) == true)
        printBoard(board);
    else
        cout << "\n\n>>>>No existe solucion...";


    return 0;
 }

bool findBlankLocation(int board[9][9], int &row, int &col)
{
    for(int row=0; row<9;row++)
        for(int col=0; col<9;col++)
            if(board[row][col] == 0)
               return true;
    return false;
}

bool inColumn(int board[9][9], int col, int number)
{
    for(int row=0; row<9; row++)
        if(number == board[row][col])
            return true;
    return false;
}

bool inRow(int board [9][9], int row, int number)
{
    for(int col=0; col<9; col++)
        if(number == board[row][col])
            return true;
    return false;
}

bool inBox(int board[9][9], int startRow, int startColumn, int num)
{
    for(int row = 0; row<3; row++)
        for(int col = 0; col<3; col++)
            if(board[row+startRow][col+startColumn] == num)
                return true;
    return false;
}

void printBoard(int board[9][9])
{
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            cout << "  " << board[i][j];
        cout << endl;
    }
}

bool blankLocation(int board[9][9], int row, int col, int num)
{
return !inColumn(board, col, num) && !inRow(board, row, num) 
&& !inBox( board,  row-row%3, col-col%3, num);
}

bool solveBoard(int board[9][9])
{
    int row, col;

    if (!findBlankLocation(board, row, col))
        return true;

    for (int num = 1; num <= 9; num++)
    {

        if (blankLocation(board, row, col, num))
        {
            board[row][col] = num;

            if (solveBoard(board))
                return true;

            board[row][col] = 0;
        }
     }

    return false;
}

2 个答案:

答案 0 :(得分:0)

bool findBlankLocation(int board[9][9], int &row, int &col)
{
    for(int row=0; row<9;row++)
        for(int col=0; col<9;col++)
            if(board[row][col] == 0)
               return true;
    return false;
}

for(int row=0; row<9;row++)定义了一个名为row的新局部变量,该变量仅存在于for循环中并隐藏int &row参数。这个循环本地row在循环退出时更新并丢失,使参数row保持不变。然后调用函数尝试使用它预期在findBlankLocation内更新的未初始化变量,并触发未定义的行为。

海湾合作委员会警告说:

  

.. \ src \ main.cpp:34:6:警告:未使用的参数'row'[-Wunused-parameter]    bool findBlankLocation(int board [9] [9],int&amp; row,int&amp; col)

如果您将警告转到第4级,Visual Studio也是如此。

  

1&gt; d:\ jobs \ consoleapplication1 \ consoleapplication1 \ consoleapplication1.cpp(36):警告C4457:'row'声明隐藏函数参数   1 GT; d:\ jobs \ consoleapplication1 \ consoleapplication1 \ consoleapplication1.cpp(34):注意:请参阅'row'的声明   1&gt; d:\ jobs \ consoleapplication1 \ consoleapplication1 \ consoleapplication1.cpp(34):警告C4100:'row':未引用的形式参数

警告可以帮到你。打开它们并注意。

同样的错误会影响col

解决方案

bool findBlankLocation(int board[9][9], int &row, int &col)
{
    for (row = 0; row < 9; row++) // now uses row parameter
        for (col = 0; col < 9; col++) // now uses col parameter
            if (board[row][col] == 0)
                return true;
    return false;
}

答案 1 :(得分:-1)

可能是由于以下块:

int row, col;

if (!findBlankLocation(board, row, col))
    return true;

因此rowcol的值未定义(与初始化为零不同)。请参阅here,了解其值未定义的原因。

更新:

经过进一步调查后,您希望findBlankLocation(board,row,col)可以通过引用返回rowcol。但事实并非如此。

bool findBlankLocation(int board[9][9], int &row, int &col)
{
  for(int row=0; row<9;row++)
    for(int col=0; col<9;col++)
      if(board[row][col] == 0)
        return true;
  return false;
}

上面的代码使用row的本地声明和col if(board[row][col] == 0)。因此,一旦找到行和列,它就返回true而不通过rowcol参数中的引用传递值。稍后,您在row函数中使用colsolveBoard,假设它们实际上不会填充有效数据。要通过引用findBlankLocation传递rowcol,它应如下所示:

bool findBlankLocation(int board[9][9], int &row, int &col)
{
  for(row = 0; row < 9; ++row)
    for(col = 0; col < 9; ++col)
      if(board[row][col] == 0)
        return true;
  return false;
}

这样您就不会重新定义rowcolrowcol实际上会包含有效数据。