数独,递归函数解决了一半的难题

时间:2014-02-02 03:37:18

标签: c++

我正在使用数独求解器,当我的程序耗尽其输出时,我的程序无法向后递归。 我有四个功能来检查: scolumnsrowsbox。如果数字已分别存在于列行或框中,则每个都将返回false。

bool sudoku::solve(int row, int column)
{
    if(column == 9)
    {
     column = 0; 
     row +=1;
    }
    if(puzzle[row][column] != 0)
    {
     solve(row, column + 1);
     return false;
    }
    else
    {
     for(int n = 0; n < 10; n ++)
     {
      if(srow(column, n) && scolumn(row,n) && sbox(row, column, n)
      {
       puzzle[row][column] = n;
       if(!solve(row, column + 1);
         table[row][column] = 0;
      }
     }
     puzzle[row][column] = 0;// if not commented out then infinite loop 
    }
   return false
}

问题在于,如果它在9处并且没有下一个选择,它将不会正确回溯。

2 个答案:

答案 0 :(得分:1)

您的代码存在许多问题,正如人们在评论中所观察到的那样。

这个答案总结了其中一些:

1)As @ n.m。说,你不应该尝试'0'作为单元格中的有效选择。毫无疑问,这将是一些无限循环的原因。

2)正如您所观察到的,您不知道递归是如何完成的。答案是,当你到达最后一个单元格,并且找到一个适用于它的值时,你应该返回true。这就是应该打破for(n)循环:该循环说“尝试每个数字直到调用此单元格右侧的成功”。成功是通过你的例程返回真实来衡量的。

由于您尝试了当前单元格中的每个数字(n),无论对其右侧的求解是否有效......都无法正常工作。

你会知道在以下情况下你的问题更加正确:

  • 当您发现可以在最后一个单元格中放置一个数字时,您可以在代码中看到返回true的位置(9,9)

  • 当右边的调用成功时,您可以看到停止尝试数字(n = 0..9)的方式。

答案 1 :(得分:0)

给定int puzzle[9][9]以及您的srowscolsbox函数:

bool sudoku::solve(int row, int column) //to solve entire puzzle, call with parameters 0 and 0
{
  int cell;

  //ignore all nonzero cells (zero = empty)
  while (row < 9 && puzzle[row][column] != 0)
  {
    column++;
    if (column == 9)
    {
      row++;
      column = 0;
    }
  }

  if (row == 9) return true; //puzzle is already solved

  //try values 1-9 inclusive.  If successful, then return true
  for (cell = 1; cell <= 9; cell++)
  {
    puzzle[row][column] = cell;
    if (srow(row) && 
        scol(column) && 
        sbox(row-row%3, column-column%3) &&
        solve(row, column)) //recursion!!
    {
        return true;
    }
  }
  //if no value works, reset the cell and return false.

  puzzle[row][column] = 0;
  return false;
}