Bor*_*der 25
在Java 8中:
final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();
Run Code Online (Sandbox Code Playgroud)
在Java 7中:
public static void main(final String[] args) throws Exception {
final Random random = new Random();
final Set<Integer> intSet = new HashSet<>();
while (intSet.size() < 6) {
intSet.add(random.nextInt(49) + 1);
}
final int[] ints = new int[intSet.size()];
final Iterator<Integer> iter = intSet.iterator();
for (int i = 0; iter.hasNext(); ++i) {
ints[i] = iter.next();
}
System.out.println(Arrays.toString(ints));
}
Run Code Online (Sandbox Code Playgroud)
只是有点麻烦.没有帮助的事实是将它拆箱Set<Integer>成一个非常繁琐的事实int[].
应该注意的是,这种解决方案应该是所需数值的精确值明显小于该范围.因为1..49比6你还好很多.否则性能会迅速降低.
JB *_*zet 11
创建一个包含数字1到49的列表.
创建一个x介于0和列表大小之间的随机数,将数字作为x列表中的索引,并将其从列表中删除.
重复上一步5次.而且你已经完成了.请注意,java.util.Random有一个nextInt(int max)方法,你应该使用而不是Math.random().
关于性能的注意事项:与"尝试直到获得6个不同数字"的各种解决方案相比,此解决方案具有优势:它在O(n)时间内运行.对于50个中的6个唯一数字来说并不重要,但是如果你想从50个中获得48或49个独特的随机数,你会开始看到差异,因为你可能必须在得到一个之前生成许多随机数那个尚未出现在集合中.
编辑:
为了减少删除列表中元素所引起的成本,您可以简单地将索引处的元素替换x为列表的最后一个元素(在第二次迭代中,元素大小为2,等等)
生成任意6个数字(不一定不同)。订购它们。
a1 <= a2 <= a3 <= a4 <= a5 <= a6
现在取这 6 个数字
a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5
这 6 个是不同的且随机的。
这种构造的想法来自一些组合证明。
它的优点是简单、快速、确定性。
我认为时间复杂度是O(count*log(count)).
我想知道是否可以改进。
import java.util.TreeMap;
public class Test005 {
public static void main(String[] args) {
int count = 6;
int min = 1;
int max = 49;
// random number mapped to the count of its occurrences
TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
for (int i=0; i<count; i++){
int d = ( min + (int) (Math.random() * (max-count+1)) );
if (!mp.containsKey(d)){
mp.put(d, 0);
}
mp.put(d, mp.get(d) + 1);
}
// now ensure the output numbers are different
int j = 0;
for (int num : mp.keySet()){
int cnt = mp.get(num);
for (int i=0; i<cnt; i++){
System.out.println(num + j);
j++;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)