我正在尝试创建一个算法,该算法可以生成一个带有随机布尔值的布尔数组,假设确切地说'x'数量的布尔值是真的。我已经解决了这个算法,但是如果有更简洁的方法,我很好奇。
以下是我工作的一个例子。两个变量songsToPlay和songsToDownload是随机生成的变量,但在这种情况下,我将它们分别设置为固定数字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++;
}
}
}
}
答案 0 :(得分:4)
我需要随机生成一个包含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);
这在O(N)时间内完成,你可以确定你有你想要的真/假数。
注意:所有解决方案都有相同的发生机会。只有在您获得所需总数之前更改值的问题是难以确保您不会对所产生的结果产生偏差。
的JavaDoc使用默认的随机源随机置换指定的列表。所有排列都以大致相等的可能性发生。
此实现向后遍历列表,从最后一个元素到第二个元素,重复地将随机选择的元素交换到&#34;当前位置&#34;。从列表中从第一个元素到当前位置(包括第一个元素)的部分中随机选择元素。
此方法以线性时间运行。如果指定的列表未实现RandomAccess接口并且很大,则此实现会在将其重新排列之前将指定的列表转储到数组中,并将重排的数组转储回进入清单。这避免了由于随机访问&#34;顺序访问而导致的二次行为。列表到位。
答案 1 :(得分:2)
随机选择四个数组索引并将其内容设置为true(并确保不要使用相同的索引两次)。
答案 2 :(得分:1)
假设你使用了一个Object数组(Boolean
而不是boolean
),只需
n
填充第一个Boolean.TRUE
,其余为Boolean.FALSE
Collections.shuffle(Arrays.asList(yourArray))
你们都已经准备好了。
答案 3 :(得分:0)
为什么不创建一个BitSet并随机将x位翻转为1.
请求的示例代码:
BitSet bs = new BitSet(songCount);
Random random = new Random();
for (int i = 0; bs.cardinality() < shuffleCount; i++) {
bs.set(random.nextInt() % songCount);
}