2012-03-16 20 views
5

Recientemente he estado trabajando en un algoritmo de resolución de sudoku retrocediendo y actualmente me gustaría preguntar cómo debo proceder para cambiar mi método solve() de vacío a un booleano.solucionador de sudoku usando retroceso

estoy usando un algoritmo de retroceso muy simple, y, actualmente, funciona muy bien, pero yo prefiero tener un valor lógico en lugar de un vacío, porque tener un printstack no es muy agradable ...

Gracias !

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; 

     } 
    } 
} 

Respuesta

4

Bueno, se podría catch excepción para evitar el seguimiento de pila, pero que aún no es muy bonita. Lo que puede hacer después de cambiar el tipo de retorno a boolean es:

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

y luego, por supuesto, cambiar las declaraciones throw a return true;.

+0

+1 para probar la captura. He realizado algunos concursos de programación donde utilicé el principio try-catch para retroceder. No es un hack elegante pero es muy útil. –

+0

Muchas gracias por eso, amigo mío, intenté cambiarlo muchas veces, pero siempre fue en vano (parecía como si estuviera estropeando las declaraciones de devolución). ¡Hice exactamente lo que tú hiciste y funciona como un amuleto! – kompsci

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; 
} 
Cuestiones relacionadas