2016-12-23 50 views
0

我試圖編寫一個方法來檢查我的Sudoku板上的重複項。目前,我的方法getFrontier()總是返回true,我發現這是因爲它只檢查一個值而不是數組或值。我在squareCheck(),rowCheck()和columnCheck()中使用該方法3次。有什麼方法可以對方法進行編碼,以便保留之前輸入的值,然後根據新值檢查它?Sudoku - 如何使用HashSet或Set?

我當前的代碼:

public class validCheck { 

public boolean isSolved(int[][][] board) 
{ 
    for(int index = 0; index < board.length;index++) 
    { 
     for(int r = 0; r < board[0].length; r++) 
     { 
      for(int c = 0; c < board[0].length;c++) 
      { 
       if(board[index][r][c] == 0) 
        return false; 
      } 
     } 
    } 
    return true; 
} 


public boolean getFrontier(int value) 
{ 
Set<Integer> reserve = new HashSet<>(); 

for(int n = 1; n < 10; n++) 
{ 
    if(value == n && reserve.contains(n)) 
     return false; 

    else if(value == n) reserve.add(n);  
} 
return true; 
} 

public boolean squareCheck(int[][][] board, int index) 
{ 
    for(int r = 0; r < board[0].length; r++) 
    { 
     for(int c = 0; c < board[0].length; c++) 
     { 
      if(!getFrontier(board[index][r][c])) 
      { 
       System.out.println("Square error at ["+index + r + c +"]"); 
       return false; 
      } 
     } 
    } 

    return true; 

} 

public boolean isValid(int[][][] board) 
{  
    if(isSolved(board)) 
    { 
     for(int i = 0; i < board.length; i++) 
     { 
      for(int r = 0; r < board[0].length;r++) 
      { 
       for(int c = 0; c < board[0].length;c++) 
       { 
        if(!rowCheck(board,i,r) || !columnCheck(board,i,c) || !squareCheck(board,i)) 
        { 
         return false; 
        } 
       } 
      } 
     } 
    } 

    return true; 

} 

public boolean columnCheck(int[][][] board, int index, int col) 
{ 
    int target = 0;  

    if(index <=2) 
    { 
     target = index + 6; 
    } 
    else if(index > 2 && index < 6) 
    { 
     target = index +3; 
     index = index - 3; 
    } 
    else if (index > 5) 
    { 
     target = index; 
     index = index - 6; 
    } 

    while(index <= target) 
    { 
     for(int r = 0; r < board[0].length;r++) 
     { 

      if(!getFrontier(board[index][r][col])) 
      { 
       System.out.println("Column error at " + index + r + col); 
       return false;  
      } 

     } 
     index = index + 3; 
    } 
    return true; 


} 


public boolean rowCheck(int[][][] board, int index, int row) 
{ 
    int target = 0; 

    if(index <= 2) 
    { 
     index = 0; 
     target = 2; 
    } 
    else if (index <= 5) 
    { 
     index = 3; 
     target = 5; 
    } 
    else if(index <= 8) 
    { 
     index = 6; 
     target = 8; 
    } 

    while(index <= target) 
    { 
      for(int c = 0; c < board[0].length; c++) 
      { 
        if(!getFrontier(board[index][row][c])) 
        { 
         System.out.println("Row error at "+index+row+c); 
         return false; 
        } 
      } 
      index++; 
     } 

     return true; 

    } 


} 

用法:

public static void main(String[] args) { 
int[][][] solved = {{{5,3,4},{6,7,2},{1,9,8}}, 
        {{6,7,8},{1,9,5},{3,4,2}}, 
        {{9,1,2},{3,4,8},{5,6,7}}, 
        {{8,5,9},{4,2,6},{7,1,3}}, 
        {{7,6,1},{8,5,3},{9,2,4}}, 
        {{4,2,3},{7,9,1},{8,5,6}}, 
        {{9,6,1},{2,8,7},{3,4,5}}, 
        {{5,3,7},{4,1,9},{2,8,6}}, 
        {{2,8,4},{6,3,5},{1,7,9}}}; 


validCheck checker = new validCheck(); 

     if(checker.isValid(solved)) 
      System.out.println(true); 

     else System.out.println(false); 
} 

任何幫助將大大感激!

+0

該方法的預期行爲是什麼?它與實際行爲有什麼不同? – pvg

+1

我會建議使用二維數組,因爲您必須在驗證有效的數獨板時檢查整列和整行是連續的 –

+0

getFrontier的用途是什麼?對我來說「前沿」是指19世紀西方的美國,或類似的東西,所以方法名稱沒有幫助,也沒有任何評論。因爲這是你想要使用'HashSet'的方法,所以我需要知道你想要這個方法做些什麼來幫助。 – ajb

回答

0

這是我會做什麼來找到一個2D數獨板中有效的板配置。我會使用一個HashSet作爲行,另一個作爲列,只要我們不會遇到重複,並且值包含1的數組長度,我們知道該板是有效的。

int [][] board = {{1,2,3}, 
         {2,3,1}, 
         {3,1,2} 
         }; 
    HashSet<Integer> rowDuplicates = new HashSet<>(); 
    HashSet<Integer> colDuplicates = new HashSet<>(); 
    boolean invalidBoard = false; 

    for(int i = 0 ; i < board.length; i++) 
    { 
     for(int j = 0; j < board[i].length; j++) 
     { 
      if(rowDuplicates.contains(board[i][j]) || colDuplicates.contains(board[j][i])) 
      { 
       //this board is not valid 
       invalidBoard = true; 
      } 
      else 
      { 
       rowDuplicates.add(board[i][j]); 
       colDuplicates.add(board[j][i]); 
      } 
     } 

     //now check they contain the correct numbers from 1 to the size of the array 
     if(colDuplicates.size() == rowDuplicates.size()) 
     { 
      for(int index = 0; index < colDuplicates.size(); index++) 
      { 
       if(!(colDuplicates.contains(index + 1) && rowDuplicates.contains(index + 1))) 
       { 
        invalidBoard = true; 
        break; 
       } 
      } 
     } 
     else 
     { 
      invalidBoard = true;  
     } 
     colDuplicates.clear(); 
     rowDuplicates.clear(); 

    } 

    System.out.println("invalid board: " + invalidBoard); 

你應該能夠擴大這個你的3D陣列,但你可以看到它是多麼容易使用HashSets驗證有效的二維數組數獨板。

+0

感謝您抽出寶貴時間輸入!我看了你的代碼後也有了一個想法,所以謝謝你!我真的希望我可以使用2D陣列,但我必須使用3D 3D ... – JAVANOOB

+0

是的,我知道但希望這將幫助你理解使用HashSets驗證Sudoku板所需的邏輯,並且可以使用它將其展開爲3D數組@JAVANOOB –