我有一个生成随机数的简单代码
SecureRandom random = new SecureRandom();
...
public int getRandomNumber(int maxValue) {
return random.nextInt(maxValue);
}
上述方法大约被调用10次(不在循环中)。我想确保所有数字都是唯一的(假设maxValue > 1000
)。
我可以确定每次打电话都会得到唯一的号码吗?如果没有,我该如何解决?
编辑:我可能模糊地说过。我想避免手动检查,如果我真的有唯一的数字,所以我想知道是否有更好的解决方案。答案 0 :(得分:5)
有不同的方法可以实现这一目标,哪种方式更合适取决于您需要从多少数字中选择多少数字。
如果可能数字的范围很小,但您需要选择的数字的数量在该范围的几个数量级内,那么您可以将其视为随机选择< / em>问题。例如,要选择10,000,000范围内的100,000个数字而不重复,我可以这样做:
设m到目前为止我选择的随机数
对于i = 1到10,000,000
生成0-1
范围内的随机(浮点)数r如果(r <(100,000-m)/(10,000,000-i)),则将i添加到列表中并递增m
随机播放列表,然后根据需要从列表中依次选择数字
但显然,如果你需要选择一些相当大比例的数字,那么选择后一种选择只有很多。为了选择1到10亿范围内的10个数字,你可以产生10亿个随机数,只要你去检查重复数据,你就不太可能真正得到重复数据,而且最终只会产生10个随机数号。
答案 1 :(得分:1)
随机序列并不意味着所有值都是唯一的。序列1,1,1,1
与序列712,4,22,424
完全一样。
换句话说,如果您希望保证一系列唯一数字,一次生成10个,检查您选择的唯一性条件并存储它们,然后从该列表中选择一个数字而不是生成随机数10个地方的数字。
答案 2 :(得分:1)
每次拨打Random#nextInt(int)
,您都会获得
伪随机,均匀分布的int值介于0(含)之间 和指定的值(不包括)。
如果您想要x
个唯一号码,请持续获取新号码,然后从该列表中选择“随机”号码。但是,由于您正在过滤生成的数字,因此它们将不再是随机的。
答案 3 :(得分:0)
对于如此少量的可能值,一个简单的实现是将1000个整数放在一个列表中,并有一个循环,在每次迭代时,生成一个介于0和list.size()
之间的随机数,存储在此索引处的数字,并将其从列表中删除。
答案 4 :(得分:0)
这是代码,CPU以内存为代价非常高效。每个potiental值为sizeof(int) * maxValue
。无符号整数最多可以达到65535。 long可以以1000个16位整数值的大量内存2000字节为代价使用。
数组的整个目的是说你之前是否使用过这个值1 = yes
'别的=否
'while循环将继续生成随机数,直到找到唯一值。
'找到一个好的随机值后,它会将其标记为已使用,然后将其返回。
'注意变量a的范围,好像它超出了你的数组可以擦除的范围。
'我在c中使用了它并且它有效。
'可能需要一点时间才能让它在Java中运行。
unsigned int a(1000);
public int getRandomNumber(int maxValue) {
unsigned int rand;
while(a(rand)==1) {
rand=random.nextInt(maxValue);
if (a(rand)!=1) { a(rand)=1; return rand;}
}
}