在这种情况下,MAX只有5,所以我可以逐个检查重复,但我怎么能以更简单的方式做到这一点?例如,如果MAX的值为20,该怎么办?谢谢.
int MAX = 5;
for (i = 1 , i <= MAX; i++)
{
drawNum[1] = (int)(Math.random()*MAX)+1;
while (drawNum[2] == drawNum[1])
{
drawNum[2] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) )
{
drawNum[3] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) )
{
drawNum[4] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[5] == drawNum[1]) ||
(drawNum[5] == drawNum[2]) ||
(drawNum[5] == drawNum[3]) ||
(drawNum[5] == drawNum[4]) )
{
drawNum[5] = (int)(Math.random()*MAX)+1;
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 143
最简单的方法是创建一个可能的数字列表(1..20或其他)然后用它们随机播放Collections.shuffle.然后只需要你想要的许多元素.如果您的范围等于最终所需的元素数量(例如,用于洗牌一副牌),这是很好的.
如果你想要(比方说)1个10,000范围内的10个随机元素,那么效果不会很好 - 你最终会不必要地做很多工作.此时,保留到目前为止生成的一组值可能更好,并且只是在循环中生成数字,直到下一个尚未存在:
if (max < numbersNeeded)
{
throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set<Integer> generated = new LinkedHashSet<Integer>();
while (generated.size() < numbersNeeded)
{
Integer next = rng.nextInt(max) + 1;
// As we're adding to a set, this will automatically do a containment check
generated.add(next);
}
Run Code Online (Sandbox Code Playgroud)
但要小心设置选项 - 我非常谨慎地使用LinkedHashSet它,因为它维护了我们关心的插入顺序.
另一种选择是通过每次缩小范围并补偿现有值来始终取得进展.因此,例如,假设您想要0到9范围内的3个值.在第一次迭代中,您将生成0..9范围内的任何数字 - 假设您生成4.
在第二次迭代中,您将生成0..8范围内的数字.如果生成的数字小于4,则按原样保留...否则添加一个.这样你得到的结果范围是0..9没有4.假设我们得到7那样的方式.
在第三次迭代中,您将生成0..7范围内的数字.如果生成的数字小于4,则保持原样.如果它是4或5,你就加一个.如果它是6或7,你将添加两个.这样结果范围是0..9,没有4或6.
Cat*_*hwa 18
这是我怎么做的
import java.util.ArrayList;
import java.util.Random;
public class Test {
public static void main(String[] args) {
int size = 20;
ArrayList<Integer> list = new ArrayList<Integer>(size);
for(int i = 1; i <= size; i++) {
list.add(i);
}
Random rand = new Random();
while(list.size() > 0) {
int index = rand.nextInt(list.size());
System.out.println("Selected: "+list.remove(index));
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如受人尊敬的Skeet先生指出:
如果n是您想要选择的随机选择数字的数量,N是可供选择的数字的总样本空间:
小智 13
//random numbers are 0,1,2,3
ArrayList<Integer> numbers = new ArrayList<Integer>();
Random randomGenerator = new Random();
while (numbers.size() < 4) {
int random = randomGenerator .nextInt(4);
if (!numbers.contains(random)) {
numbers.add(random);
}
}
Run Code Online (Sandbox Code Playgroud)
这会简单得多java-8:
Stream.generate(new Random()::ints)
.flatMap(IntStream::boxed)
.distinct()
.limit(16) // whatever limit you might need
.toArray(Integer[]::new);
Run Code Online (Sandbox Code Playgroud)
还有另一种用 LFSR 做“随机”有序数字的方法,看看:
http://en.wikipedia.org/wiki/Linear_feedback_shift_register
使用这种技术,您可以通过索引获得有序的随机数,并确保值不重复。
但这些不是真正的随机数,因为随机生成是确定性的。
但是根据您的情况,您可以使用此技术减少使用改组时随机数生成的处理量。
这是java中的LFSR算法,(我把它带到了我不记得的地方):
public final class LFSR {
private static final int M = 15;
// hard-coded for 15-bits
private static final int[] TAPS = {14, 15};
private final boolean[] bits = new boolean[M + 1];
public LFSR() {
this((int)System.currentTimeMillis());
}
public LFSR(int seed) {
for(int i = 0; i < M; i++) {
bits[i] = (((1 << i) & seed) >>> i) == 1;
}
}
/* generate a random int uniformly on the interval [-2^31 + 1, 2^31 - 1] */
public short nextShort() {
//printBits();
// calculate the integer value from the registers
short next = 0;
for(int i = 0; i < M; i++) {
next |= (bits[i] ? 1 : 0) << i;
}
// allow for zero without allowing for -2^31
if (next < 0) next++;
// calculate the last register from all the preceding
bits[M] = false;
for(int i = 0; i < TAPS.length; i++) {
bits[M] ^= bits[M - TAPS[i]];
}
// shift all the registers
for(int i = 0; i < M; i++) {
bits[i] = bits[i + 1];
}
return next;
}
/** returns random double uniformly over [0, 1) */
public double nextDouble() {
return ((nextShort() / (Integer.MAX_VALUE + 1.0)) + 1.0) / 2.0;
}
/** returns random boolean */
public boolean nextBoolean() {
return nextShort() >= 0;
}
public void printBits() {
System.out.print(bits[M] ? 1 : 0);
System.out.print(" -> ");
for(int i = M - 1; i >= 0; i--) {
System.out.print(bits[i] ? 1 : 0);
}
System.out.println();
}
public static void main(String[] args) {
LFSR rng = new LFSR();
Vector<Short> vec = new Vector<Short>();
for(int i = 0; i <= 32766; i++) {
short next = rng.nextShort();
// just testing/asserting to make
// sure the number doesn't repeat on a given list
if (vec.contains(next))
throw new RuntimeException("Index repeat: " + i);
vec.add(next);
System.out.println(next);
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法,它允许您指定多少个号码想size与min和max值返回的数字
public static int getRandomInt(int min, int max) {
Random random = new Random();
return random.nextInt((max - min) + 1) + min;
}
public static ArrayList<Integer> getRandomNonRepeatingIntegers(int size, int min,
int max) {
ArrayList<Integer> numbers = new ArrayList<Integer>();
while (numbers.size() < size) {
int random = getRandomInt(min, max);
if (!numbers.contains(random)) {
numbers.add(random);
}
}
return numbers;
}
Run Code Online (Sandbox Code Playgroud)
使用它返回 0 到 25 之间的 7 个数字。
ArrayList<Integer> list = getRandomNonRepeatingIntegers(7, 0, 25);
for (int i = 0; i < list.size(); i++) {
System.out.println("" + list.get(i));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
251446 次 |
| 最近记录: |