2012-03-16 23 views
5

Gần đây tôi đã làm việc trên một thuật toán giải thuật sudoku backtracking và hiện tại tôi muốn hỏi về cách tôi nên thay đổi phương thức resolve() của tôi từ void thành boolean.sudoku solver bằng cách sử dụng backtracking

Tôi đang sử dụng một thuật toán quay lui rất đơn giản, và nó hiện đang làm việc tốt, nhưng tôi muốn có một boolean thay vì một khoảng trống, bởi vì có một printstack không phải là rất tốt đẹp ...

Cảm ơn !

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; 

     } 
    } 
} 

Trả lời

4

Vâng, bạn có thể catch ngoại lệ để tránh theo dõi ngăn xếp, nhưng điều đó vẫn không đẹp lắm. Những gì bạn có thể làm sau khi thay đổi kiểu trả về để boolean là:

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

và sau đó tất nhiên, thay đổi throw báo cáo để return true;.

+0

+1 để bắt thử. Tôi đã thực hiện một số cuộc thi lập trình mà tôi đã sử dụng nguyên tắc try-catch để quay lại. Nó không phải là một hack thanh lịch nhưng nó rất hữu ích. –

+0

Cảm ơn rất nhiều vì người bạn của tôi, tôi đã cố gắng thay đổi nó rất nhiều lần, nhưng luôn vô ích (có vẻ như tôi đang làm rối tung những câu trả lời). Tôi đã làm chính xác những gì bạn đã làm và nó hoạt động như một sự quyến rũ! – 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; 
}