随机填充具有相等两个值的2d布尔数组

时间:2015-02-03 23:35:40

标签: java arrays

我正试图找到一种方法来填充长度为n的2d数组,其中布尔值是随机的。如果n是偶数,则数组必须具有相等数量的每个值,并且如果n是奇数,则额外值必须每次都是相同的布尔值(无关紧要)。有关如何在Java中执行此操作的任何提示?我目前正在使用相同数量的两个值来改变阵列,但这并不是真正随机的,因为总是有n / 2(或n / 2 + 1和n / 2-1,奇数ns)每个值。

有什么建议吗?

4 个答案:

答案 0 :(得分:1)

根据您的要求,使用您需要的数量填充阵列,然后将其洗牌,这是一个很好的解决方案。

确保使用真正随机的混洗算法,例如Fisher-Yates shuffle,而不是“多次交换随机对”方法。如果您使用Collections.shuffle或类似内容,则无需担心此问题。

答案 1 :(得分:0)

将Fisher-Yates shuffle调整为2D数组可能是最简单的方法。

 boolean[][] array = new boolean[rows][cols];
 boolean alternating = false;
 Random random = new Random();
 for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      int k = random.nextInt(i * cols + j + 1);
      int swapRow = k / cols;
      int swapCol = k % cols;
      boolean tmp = array[swapRow][swapCol];
      array[swapRow][swapCol] = alternating;
      array[i][j] = tmp;
      alternating = !alternating;
    }
 }

这几乎是http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_.22inside-out.22_algorithm的逐字实现,除了我们在愚蠢和真实地填充数组时。

答案 2 :(得分:0)

另一种方法可能是将您放置下一个值而不是值本身的位置随机化。您提前知道您正在放置的每个值中有多少。

类似的东西:

List<Integer> indicesList = IntStream.range(0, n * n).collect(Collectors.toList());
Collections.shuffle(indicesList);
indicesList.stream().forEach(n -> array[n % size][n / size] = (n % 2 == 0));

根据我的理解,应该让您完全随意放置您的值和相同数量的每个。

答案 3 :(得分:0)

这是一个同事想出的真正简单的解决方案。在我看来它会起作用并且是真正的随机(如果没有,请告诉我,我对这种事情有可怕的直觉),尽管它绝对是丑陋的。与我想象的洗牌相比,效率会非常高。

public boolean[][] generateRandom2dBooleanArray(int length) {
    int numFalses = (length*length)/2;
    int numTrues = (length*length)/2;
    if ((length*length)%2!=0) numTrues++; 

    boolean[][] array = new boolean[length][length];

    for (int i = 0; i < array.length; i++) {
        for (int j = 0; j < array.length; j++) {

            if (Math.random() > 0.5) {//Or is it >= 0.5?  
                    if (numTrues >= 0) {
                        array[i][j] = true;
                        numTrues--;
                    } else {
                        //Since boolean arrays are false by default, you could probably just break here to get the right anser, but...
                        array[i][j] = false;
                        numFalses--;
                    }
                } else {
                    if (numFalses >= 0) {
                        array[i][j] = false;
                        numFalses--;
                    } else {
                        array[i][j] = true;
                        numTrues--;
                    }
                }
            }
        }
    }

    return array;
}