Java 在二维数组中生成唯一的行和列

Java 在二维数组中生成唯一的行和列,java,arrays,random,Java,Arrays,Random,我随机填充了一个二维数组,但我希望每行和每列中生成的数字都是唯一的。这是我使用的代码 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++) {

我随机填充了一个二维数组,但我希望每行和每列中生成的数字都是唯一的。这是我使用的代码

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();
    }
但我期待着这样的事情

1 2 3 
3 1 2 
2 3 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();
}


因此,它确保您始终有足够的
不同的
数字来生成

在我看来,您试图创建一个类似于数独板的矩阵,只是您没有要求检查每个单独的3x3子矩阵

如果您计划使用9x9矩阵。不太可能对所有81个元素都使用“随机”。(可以,但生成董事会所需的时间可能要长得多)

这是您可以做的:

  • 创建2个数组以跟踪当前行/列是否已包含1-9
  • 创建一组要从中拾取的数字(数字范围遵循矩阵大小)
  • 在第一行中随机填入1-9
  • 通过检查是否可以填充,以递归方式用数字填充空框
  • 填充数字时,请将其从数字集中删除
  • 如果存在冲突,返回到最后一个已知的良好位置并继续

我用蛮力方法解决了这个问题,效果很好。 生成一个独特的9 x 9板不到1秒

输出:

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);  
}
publicstaticvoidmain(字符串[]args){
int size=9;
int[][]板=新int[size][size];
board[0]=Util.createOrderedArray(大小为1);

对于(int x=1;x)这个输出看起来像我期望从这段代码中得到的。它是纯的(伪的)随机…我知道,我想给它设置一些条件,以便在行或列中出现重复时可以重新生成它。@您将使用的最大2D数组大小是多少?只有3 x 3?我计划9 x 9,并计划随机生成从1到9的数字。@好消息是,我刚刚尝试用蛮力方法对其进行编码,生成9x9唯一矩阵不到1秒。如果您想让我发布代码,请告诉我。我认为“set.contains”后面必须有内容。我们希望在之后会反对it@AND对不起,我忘了在它前面添加
(如果它
不包含).我已经给出了答案,ty@nafas我认为这个解决方案有一个潜在的问题。当第1行有
1,2,3
时,如何防止第2行变成
2,1,3
?@user3437460查看所需的输出匹配,第2行确实可以变成
2,1,3
,就像第1行是
1,2,3
,而第2行是
2,1,3
。最后一列是不再是唯一的。
3
在最后一列中重复。备注:我创建的Util类是灵活的。您可以执行
Util.shuffle(board[0]);
以使第一行不再排序。您也可以创建不同大小的矩阵。但是,大小超过10的矩阵可能需要更长的处理时间。
int next= randomGenerator.nextInt(values[i].length) + 1;
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);  
}
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(""); 
        }                           
    }
}