数独求解器使用回溯算法

6

最近我一直在研究回溯数独求解算法,目前我想请教如何将我的solve()方法从void更改为boolean。

我使用的是非常简单的回溯算法,目前它运行良好,但我希望有一个布尔值而不是void,因为打印堆栈并不好看...

谢谢!

public class Backtracking{


 static int backtrack = 0;


 //check if valid in row
protected static boolean validInRow(int row, int value)
{
   for( int col = 0; col < 9; col++ )
     if( board[row][col] == value )
         return false ;

  return true ;
}

  //check if valid in column
protected static boolean validInCol(int col, int value)
{
    for( int row = 0; row < 9; row++ )
     if( board[row][col] == value )
        return false ;

  return true ;
 }

 //check if valid in 3*3
protected static boolean validInBlock(int row, int col, int value)
{
  row = (row / 3) * 3 ;
    col = (col / 3) * 3 ;

   for( int r = 0; r < 3; r++ )
      for( int c = 0; c < 3; c++ )
       if( board[row+r][col+c] == value )
         return false ;

   return true ;
 }




      //call other methods
public void solve(int row, int col) throws Exception
{

   if(row > 8)
     throw new Exception("Solution found") ;
  else
  {

     while(board[row][col] != 0)
     {
        if( ++col > 8 )
        {
           col = 0 ;
           row++ ;


           if( row > 8 )
              throw new Exception( "Solution found" ) ;
        }
     }


     for(int value = 1; value < 10; value++)
     {
        if(validInRow(row,value) && validInCol(col,value) && validInBlock(row,col,value))
        {
           board[row][col] = value;
           new PrintEvent(board);



           if( col < 8 )
              solve(row, col + 1);
           else
              solve(row + 1, 0);

           backtrack++;
         }
      }


      board[row][col] = 0;

      }
   }
 }
2个回答

4

好的,你可以 捕获 异常来避免堆栈跟踪,但这仍然不太美观。修改返回类型为 boolean 后,您可以执行以下操作:

       if( col < 8 ) {
          if (solve(row, col + 1)) {
              return true;
          }
       } else {
          if (solve(row + 1, 0)) {
              return true;
          }
       }

然后,当然要将throw语句更改为return true;


加一票支持try-catch。我曾经参加过一些编程比赛,使用了try-catch原则进行回溯。它虽然不是特别优雅的方法,但是非常实用。 - Willem Van Onsem
非常感谢你,我的朋友。我尝试过很多次去更改它,但总是徒劳无功(似乎我搞砸了返回语句)。我按照你的方法做了,现在它完美地工作了! - zak.oud

0
public boolean solve(int row, int col) throws Exception
{
  {

     while(board[row][col] != 0)
     {
        if( ++col > 8 )
        {
           col = 0 ;
           row++ ;


           if( row > 8 )
             return true
        }
     }


     for(int value = 1; value < 10; value++)
     {
        if(validInRow(row,value) && validInCol(col,value) && validInBlock(row,col,value))
        {
           board[row][col] = value;
           new PrintEvent(board);



           if( col < 8 )
              solve(row, col + 1);
           else
              solve(row + 1, 0);

           backtrack++;
         }
      }


      board[row][col] = 0;

      }
   }
return false;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接