2015-09-25 51 views
3

我隨機填充2維數組,但我希望每行和列中生成的數字都是唯一的。下面是我用在2維數組中生成唯一的行和列

int[][] values = new int[3][3]; 

    Random randomGenerator = new Random(); 
    for (int i = 0; i < values.length; i++) { 

     int[] sub = values[i]; 
     for (int x = 0; x < sub.length; x++) { 
      sub[x]= randomGenerator.nextInt(4);; 
     System.out.print(sub[x] + " "); 
     } 
     System.out.println(); 
    } 

我的電流輸出和所產生的數字是隨機的

2 2 2 
3 2 0 
0 2 1 

但我希望這樣的事情

1 2 3 
3 1 2 
2 3 1 
+0

這個輸出看起來像我期望從這個代碼。它是純粹的(僞)隨機... – dotvav

+0

我知道,我想給它一些條件,以便我可以重新生成它incase在行或列有重複。 –

+1

@AND您將使用的最大可能的二維數組大小是多少?只有3 x 3? – user3437460

回答

1

我想這個問題與蠻力的方法和它的工作原理。 花費不到1秒生成一個獨特的9×9板。

輸出:

1 2 3 4 5 6 7 8 9 
2 6 8 9 7 4 1 3 5 
6 3 5 7 9 1 2 4 8 
9 5 4 8 6 2 3 1 7 
5 4 7 1 2 8 9 6 3 
8 1 9 6 3 7 5 2 4 
4 9 2 3 8 5 6 7 1 
7 8 6 5 1 3 4 9 2 
3 7 1 2 4 9 8 5 6 

下面是我的代碼:

public static void main(String[] args){ 
    int size = 9; 

    int[][] board= new int[size][size]; 
    board[0] = Util.createOrderedArray(size, 1); 

    for(int x=1; x<size; x++){   
     board[x] = Util.createOrderedArray(size, 1); 
     do{ 
      Util.shuffle(board[x]); 
     }while(!Util.compare2DArray(board[x], board, 0, x));   
    }  
    Util.print(board); 
} 

我寫了一個自定義的Util類中的所有幫助我的方法。

final class Util 
{ 
    public static void shuffle(int[] num){ 
     Random rnd = new Random(); 
     for(int x=0; x<num.length; x++) 
      swap(num, x, rnd.nextInt(num.length)); 
    } 

    public static void swap(int[] num, int a, int b){ 
     int temp = num[a]; 
     num[a] = num[b]; 
     num[b] = temp; 
    } 

    public static int[] createOrderedArray(int size, int startValue){ 
     int[] num = new int[size]; 
     for(int x=0; x<num.length; x++) 
      num[x] = x+startValue;  
     return num; 
    } 

    //Return TRUE if array vs arrays is COMPLETELY different 
    public static boolean compare2DArray(int[] num1, int[][] num2, int start, int end){ 
     for(int x=start; x<end; x++) 
      if(!compareArray(num1, num2[x])) 
       return false; 
     return true;   
    } 

    //Return TRUE if arrays are COMPLETELY different 
    public static boolean compareArray(int[] num1, int[] num2){ 
     if(num1.length != num2.length) 
      return false; 
     for(int x=0; x<num1.length; x++) 
      if(num1[x] == num2[x]) 
       return false; 
     return true;   
    } 

    public static void print(int[][] num){ 
     for(int x=0; x<num.length; x++){ 
      for(int y=0; y<num[0].length; y++) 
       System.out.print(num[x][y] + " "); 
      System.out.println(""); 
     }       
    } 
} 

這是通過強力方法來完成。如果你想優雅地做,它會更有效率,如果我們遞歸地做,所以沒有不必要的循環浪費。

+1

**備註:**我創建的Util類是靈活的。您可以執行'Util.shuffle(board [0]);'以便不再排序第一行。您還可以創建不同大小的矩陣。但是,大於10的矩陣可能需要更長的時間來處理。 – user3437460

1

這裏,這可能更改代碼是這樣做的一種方式。

您可以跟蹤生成的數字,如果再次生成,則忽略它們。

我使用Set,因爲它不允許重複的值。但我相信任何其他集合都應該這樣做。

int[][] values = new int[3][3]; 

Random randomGenerator = new Random(); 
for (int i = 0; i < values.length; i++) { 
    Set<Integer> set= new HashSet<Integer>(); 
    int[] sub = values[i]; 
    for (int x = 0; x < sub.length;) { 
     int next= randomGenerator.nextInt(4) + 1;// +1 ensure a number in {1,2,3} 

     if(!set.contains){ 
      sub[x]= next; 
      set.add(next); 
      x++; //note we only add the variable if non-duplicate values were generated. 
      System.out.print(sub[x] + " "); 
     } 

    } 
    System.out.println(); 
} 

注意,

如果你試圖改變你的數組的大小,它能夠更好地改變

int next= randomGenerator.nextInt(4) + 1; 

int next= randomGenerator.nextInt(values[i].length) + 1; 

所以確保你始終有足夠的distinct數字來生成

+0

我認爲必須遵循「set.contains」。我們希望能在它之後反對 –

+1

@AND對不起,我忘了在它之前加上'!'(所以如果它不包含)。我已經編輯了答案,ty – nafas

+0

@nafas我認爲這個解決方案有一個潛在的問題。當row1有'1,2,3'時,如何防止row2變成'2,1,3'? – user3437460

2

在我看來,你試圖創建一個類似於Sudoku板的矩陣,除非你沒有要求檢查每個單獨的3x3子矩陣。

如果您計劃使用9x9矩陣。所有81個元素都不可能隨機使用。 (可以,但可能需要比生成電路板所需時間長得多的時間)。

這是你可以做什麼:

  • 跟蹤當前的行/列是否已經有1-9
  • 創建一組數字從挑創建2門陣列(編號範圍如下矩陣大小)
  • 用1-9隨機填寫第一行。
  • 通過檢查是否可以填充,遞歸地填充帶有數字的空框。
  • 當您填寫一個數字,從一組數字中刪除它
  • 如果有衝突,原路返回到最近一次的正確位置,並繼續