Java:生成一个恰好为“x”真的随机布尔数组 - 算法

AMo*_*abi 1 java arrays random algorithm boolean

我正在尝试创建一个算法,该算法可以生成一个带有随机布尔值的布尔数组,因为布尔值的数量正好是“x”。我已经解决了算法,但很好奇是否有更简洁的方法来做到这一点。

下面是我工作的一个例子。两个变量songToPlay 和songToDownload 是随机生成的变量,但在这种情况下,我将它们分别设置为固定数字8 和4。另一个需要提及的重点是数组中的第一个布尔值必须为真。

问题:我需要随机生成一个包含 8 个真值和假值的数组,其中正好有 4 个值为真。

Random ran = new Random();
    int songsToPlay = 8;
    int songsToDl = 4
    Boolean[] ranDownloads = new Boolean[songsToPlay];
    ranDownloads[0] = true;
    int counter = 1; //track how many are true, given the first one is always true.

    for(int i = 1; i < ranDownloads.length; i++) {
            if((songsToDl - counter) >= (ranDownloads.length - i)) {
                ranDownloads[i] = true;
                counter++;
            } else {
                if(counter == songsToDl) {
                    while (i < ranDownloads.length) {
                        ranDownloads[i++] = false;
                    }
                break;
                } else {
                ranDownloads[i] = ran.nextBoolean();
                if(ranDownloads[i] == true) {
                    counter++;                      
                }
                }
            }

    }
Run Code Online (Sandbox Code Playgroud)

Pet*_*rey 6

我需要随机生成一个包含 8 个真值和假值的数组,其中正好有 4 个值为真。

这是洗牌问题的变种

List<Boolean> flags = new ArrayList<Boolean>();
for(int i = 0; i < 4; i++) flags.add(true);
for(int i = 0; i < 4; i++) flags.add(false);
Collections.shuffle(flags);
Run Code Online (Sandbox Code Playgroud)

这在 O(N) 时间内完成,您可以确定您拥有所需的真/假数量。

注意:所有解决方案的发生机会均等。在获得所需总数之前仅更改值的问题是很难确保您产生的结果没有偏差。

来自Collections.shuffle(List)的 JavaDoc

使用默认的随机源随机排列指定的列表。所有排列都以近似相等的可能性发生。

此实现向后遍历列表,从最后一个元素到第二个元素,反复将随机选择的元素交换到“当前位置”。元素是从列表中从第一个元素到当前位置(含)的部分中随机选择的。

此方法在线性时间内运行。如果指定的列表未实现 RandomAccess 接口并且很大,则此实现将指定的列表转储到数组中,然后再将其混洗,并将混洗后的数组转储回列表。这避免了由于将“顺序访问”列表改组到位而导致的二次行为。