Java 创建无重复的随机数
在本例中,最大值仅为5,因此我可以逐个检查重复项,但如何以更简单的方式执行此操作?例如,如果最大值为20,该怎么办? 谢谢Java 创建无重复的随机数,java,random,Java,Random,在本例中,最大值仅为5,因此我可以逐个检查重复项,但如何以更简单的方式执行此操作?例如,如果最大值为20,该怎么办? 谢谢 int MAX=5; 对于(i=1,i而言,最简单的方法是创建一个可能的数字列表(1..20或任何数字),然后使用集合对其进行洗牌。洗牌。然后只需选择您想要的元素数量。如果您的范围等于最终需要的元素数量(例如,洗牌一副牌),这将非常好 如果你想要(比如)10个1..10000范围内的随机元素,那就不太好了-你最终会做很多不必要的工作。在这一点上,最好保留一组迄今为止生成的值
int MAX=5;
对于(i=1,i而言,最简单的方法是创建一个可能的数字列表(1..20或任何数字),然后使用集合对其进行洗牌。洗牌。然后只需选择您想要的元素数量。如果您的范围等于最终需要的元素数量(例如,洗牌一副牌),这将非常好
如果你想要(比如)10个1..10000范围内的随机元素,那就不太好了-你最终会做很多不必要的工作。在这一点上,最好保留一组迄今为止生成的值,并在循环中不断生成数字,直到下一个数字还没有出现:
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);
}
if(所需的最大值
但是,在选择集合时要小心——我非常有意地使用了LinkedHashSet
,因为它维护了插入顺序,这一点我们在这里关注
另一个选择是始终取得进展,每次缩小范围并补偿现有值。因此,例如,假设您想要3个范围为0..9的值。在第一次迭代中,您将生成范围为0..9的任何数字-假设您生成了4
在第二次迭代中,您将生成一个范围为0..8的数字。如果生成的数字小于4,您将保持原样…否则您将向其中添加一个。这将得到一个0..9的结果范围,没有4。假设这样得到7
在第三次迭代中,您将生成一个范围为0..7的数字。如果生成的数字小于4,您将保持原样。如果是4或5,您将添加一个。如果是6或7,您将添加两个。这样,结果范围为0..9,没有4或6。我将这样做
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));
}
}
}
import java.util.ArrayList;
导入java.util.Random;
公开课考试{
公共静态void main(字符串[]args){
int size=20;
ArrayList list=新的ArrayList(大小);
对于(int i=1;i 0){
int index=rand.nextInt(list.size());
System.out.println(“所选:“+列表.删除(索引));
}
}
}
正如尊敬的斯基特先生所指出的:
如果n是您希望选择的随机选择的数字的数量,n是可供选择的数字的总样本空间:
如果n有卡片批处理的算法:您创建有序的数字数组(“卡片批处理”),并在每次迭代中从中随机选择一个数字(当然从“卡片批处理”中删除所选数字)。您可以使用实现Set接口的类之一(),然后使用Set.add()插入生成的每个数字
如果返回值为false,则表示之前已经生成了该数字。是快速创建随机化数组的有效解决方案。随机化后,您只需选择数组的n
-th元素e
,递增n
并返回e
。此解决方案具有O(1)用于获取一个随机数,O(n)用于初始化,但作为一种折衷,如果n足够大,则需要大量内存。不要执行所有这些操作,而是创建一个LinkedHashSet
对象并通过Math.random()向其添加随机数
函数…如果出现任何重复项,LinkedHashSet
对象将不会将该数字添加到其列表中…因为在此集合类中不允许重复值..最后,您将得到一个没有重复值的随机数列表..:D//随机数为0,1,2,3
//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);
}
}
public class NewClass {
public List<Integer> keys = new ArrayList<Integer>();
public int rand(int m) {
int n = (int) (Math.random() * m + 1);
if (!keys.contains(n)) {
keys.add(n);
return n;
} else {
return rand(m);
}
}
public static void main(String[] args) {
int m = 4;
NewClass ne = new NewClass();
for (int i = 0; i < 4; i++) {
System.out.println(ne.rand(m));
}
System.out.println("list: " + ne.keys);
}
}
ArrayList编号=新的ArrayList();
Random randomGenerator=新的Random();
while(number.size()<4){
int random=randomGenerator.nextInt(4);
如果(!number.contains(随机)){
数字。添加(随机);
}
}
对于整数,有一种比Collections.shuffle更高效、更简单的解决方案
这个问题与仅从一组中未拾取的项目中连续拾取项目并在其他地方将其按顺序排列是一样的。这与随机发牌或从帽子或箱子中抽取中奖彩票完全相同
此算法适用于加载任何数组并在加载结束时实现随机顺序。它还适用于添加到列表集合(或任何其他索引集合)并在添加结束时实现集合中的随机序列
可以使用单个数组(创建一次)或按数字顺序排列的集合(如列表)执行此操作。对于数组,初始数组大小必须是包含所有预期值的精确大小。如果您不知道可能提前出现多少值,请使用按数字顺序排列的集合(如ArrayList或List),其中大小不是不变的,它也可以工作。它适用于任何大小的数组,最大值为Integer.MAX_,略大于2000000000。列表对象将具有相同的索引限制。在获得该大小的数组之前,您的计算机可能会内存不足。加载按对象类型键入的数组和加载数组后,将其转换到某个集合。如果目标集合没有数字索引,则尤其如此
正如所写的,这个算法将创建一个非常均匀的分布,其中没有重复
// RandomSequence.java
import java.util.Random;
public class RandomSequence {
public static void main(String[] args) {
// create an array of the size and type for which
// you want a random sequence
int[] randomSequence = new int[20];
Random randomNumbers = new Random();
for (int i = 0; i < randomSequence.length; i++ ) {
if (i == 0) { // seed first entry in array with item 0
randomSequence[i] = 0;
} else { // for all other items...
// choose a random pointer to the segment of the
// array already containing items
int pointer = randomNumbers.nextInt(i + 1);
randomSequence[i] = randomSequence[pointer];
randomSequence[pointer] = i;
// note that if pointer & i are equal
// the new value will just go into location i and possibly stay there
// this is VERY IMPORTANT to ensure the sequence is really random
// and not biased
} // end if...else
} // end for
for (int number: randomSequence) {
System.out.printf("%2d ", number);
} // end for
} // end main
} // end class RandomSequence
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);
}
}
}
// get 5 unique random numbers, possible values 0 - 19
// (assume desired number of selections < number of choices)
const int POOL_SIZE = 20;
const int VAL_COUNT = 5;
declare Array mapping[POOL_SIZE];
declare Array results[VAL_COUNT];
declare i int;
declare r int;
declare max_rand int;
// create mapping array
for (i=0; i<POOL_SIZE; i++) {
mapping[i] = i;
}
max_rand = POOL_SIZE-1; // start loop searching for maximum value (19)
for (i=0; i<VAL_COUNT; i++) {
r = Random(0, max_rand); // get random number
results[i] = mapping[r]; // grab number from map array
mapping[r] = max_rand; // place item past range at selected location
max_rand = max_rand - 1; // reduce random scope by 1
}
public static int newRandom(int limit){
return generatedRandom.nextInt(limit); }
public static int testDuplicates(int int1, int int2, int int3, int int4, int int5){
boolean loopFlag = true;
while(loopFlag == true){
if(int1 == int2 || int1 == int3 || int1 == int4 || int1 == int5 || int1 == 0){
int1 = newRandom(75);
loopFlag = true; }
else{
loopFlag = false; }}
return int1; }
num1 = newRandom(limit1);
num2 = newRandom(limit1);
num3 = newRandom(limit1);
num4 = newRandom(limit1);
num5 = newRandom(limit1);
num1 = testDuplicates(num1, num2, num3, num4, num5);
num2 = testDuplicates(num2, num1, num3, num4, num5);
num3 = testDuplicates(num3, num1, num2, num4, num5);
num4 = testDuplicates(num4, num1, num2, num3, num5);
num5 = testDuplicates(num5, num1, num2, num3, num5);
int getValue(i)
{
if (map.contains(i))
return map[i];
return i;
}
void setValue(i, val)
{
if (i == val)
map.remove(i);
else
map[i] = val;
}
int[] chooseK(int n, int k)
{
for (int i = 0; i < k; i++)
{
int randomIndex = nextRandom(0, n - i); //(n - i is exclusive)
int desiredIndex = n-i-1;
int valAtRandom = getValue(randomIndex);
int valAtDesired = getValue(desiredIndex);
setValue(desiredIndex, valAtRandom);
setValue(randomIndex, valAtDesired);
}
int[] output = new int[k];
for (int i = 0; i < k; i++)
{
output[i] = (getValue(n-i-1));
}
return output;
}
items i0 i1 i2 i3 i4 i5 i6 (total 7 items)
idx 0 ^^ (index 2)
items i0 i1 i3 i4 i5 i6 (total 6 items)
idx 1 ^^ (index 2 out of these 6, but 3 out of the original 7)
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;
}
ArrayList<Integer> list = getRandomNonRepeatingIntegers(7, 0, 25);
for (int i = 0; i < list.size(); i++) {
System.out.println("" + list.get(i));
}
Stream.generate(new Random()::ints)
.flatMap(IntStream::boxed)
.distinct()
.limit(16) // whatever limit you might need
.toArray(Integer[]::new);
public class NewClass {
public List<Integer> keys = new ArrayList<Integer>();
public int rand(int m) {
int n = (int) (Math.random() * m + 1);
if (!keys.contains(n)) {
keys.add(n);
return n;
} else {
return rand(m);
}
}
public static void main(String[] args) {
int m = 4;
NewClass ne = new NewClass();
for (int i = 0; i < 4; i++) {
System.out.println(ne.rand(m));
}
System.out.println("list: " + ne.keys);
}
}
Random r = new Random();
int randomNumberOrigin = 0;
int randomNumberBound = 10;
int size = 5;
int[] unique = r.ints(randomNumberOrigin, randomNumberBound)
.distinct()
.limit(size)
.toArray();
Random random = new Random();
Integer[] input9 = IntStream.range(1, 10).map(i -> random.nextInt(1000)).boxed().distinct()
.toArray(Integer[]::new);
System.out.println(Arrays.toString(input9));