繁体   English   中英

如何防止重叠的随机数

[英]How can I prevent the overlapping random numbers

我将如何防止从随机数重复数字。 我需要生成1和9之间的5个数字,每个数字都不相同。 我经常会得到像23334这样的数字,我该如何防止呢? 任何帮助将是巨大的!

    int num2 = (int) Math.round((Math.random()*9) +1);
    int num1 = (int) Math.round((Math.random()*9) +1);
    int num5 = (int) Math.round((Math.random()*9) +1);
    int num3 = (int) Math.round((Math.random()*9) +1);
    int num4 = (int) Math.round((Math.random()*9) +1);

一种选择是使用随机播放算法(例如Fisher-Yates shuffle )生成1到9之间的随机序列,然后取序列的前5个数字

有关StackOverflow的进一步说明: https ://stackoverflow.com/a/196065/950427

Set<Integer> set=new HashSet<>();
while (set.size()<5) {
    set.add( Math.round((Math.random()*9) +1));
}

填满集合后,您将获得5个唯一的随机数。

更新:只是为了说明Jared Burrows的评论

  1. 创建一个列表,其中包含所需的数字(1到9)。
  2. 生成从0到(列表大小减去1)的随机数。
  3. 从上面生成的随机数中按索引删除一个元素。 并将删除的元素添加到要作为结果返回的数组中

     public static void main(String[] args) { int []answers= returnRandomNonRepeatingNumbers(5,0,9); for(int answer: answers) { System.out.println(answer); } } public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) { List<Integer> pool=new ArrayList<Integer>(); for(int i=poolStart;i<=poolEnd;i++) { pool.add(i); } int []answers=new int[sizeYouWant]; for(int i=0;i<sizeYouWant;i++) { //random index to be pick and remove from pool int randomIndex = (int) Math.round((Math.random()*(pool.size()-1))); answers[i]=pool.remove(randomIndex); } return answers; } 

如果可能的随机值数量很少,则需要使用随机播放。

List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);

如果可能的随机值数量很大,则需要测试将其添加到Set中(如果足够小,则将其添加到原始列表中)

Set<Integer> valueSet = new HashSet<>(); 
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);

注意:您需要重新整理集合,因为它不会保留顺序。 例如,数字1,2,3将始终通过HashSet而不是3,2,1依次出现。

Floyd的子集选择算法旨在准确地完成您想要的事情,即使对于大型集合也非常有效。 n个集合中选择m项是O(m)平均运行时间,与n无关。 这是一个Java实现。

/*
 * Floyd's algorithm to chose a random subset of m integers
 * from a set of n, zero-based.
 */
public static HashSet<Integer> generateMfromN(int m, int n) {
   HashSet<Integer> s = new HashSet<Integer>();
   for (int j = n-m; j < n; ++j) {
      if(! s.add((int)((j+1) * Math.random()))) {
         s.add(j);
      }
   }
   return s;
}

我想您需要将已生成的数据存储到数组中,并将新的随机数与列表进行比较以确保其唯一性。

public static void main (String[] args) throws java.lang.Exception
{
    // your code goes here
    int[] numbers = new int[5];
    int tempNumber = 0;

    for(int numberCounter = 0; numberCounter < numbers.length;)
    {
        tempNumber = (int) Math.round((Math.random()*9) +1);

        if(!contains(numbers, tempNumber)){
            numbers[numberCounter++] = tempNumber;
        }
    }
}

public static boolean contains(final int[] numbersArray, final int tempNumber) {
    for (final int numberFromArray : numbersArray) {
        if (numberFromArray == tempNumber) {
            return true;
        }
    }
    return false;
} 

我注意到您在示例中未使用数组,因此如果您还不知道如何使用它们,则还可以创建5个变量。

int randomNumber = 0;

int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;

while(secondNumber == 0){
    randomNumber = Math.round((Math.random()*9) +1)l
    if(randomNumber != firstNumber){
        secondNumber = randomNumber;
    }
}

您可以继续进行while语句。 但是,如果您应该了解数组,则绝对应该使用一个来存储数字。

解决此问题的一种可能方法是分而治之。 以下步骤描述了该方法:

  1. 假设m是最小值, n是最大值,在此范围内,我想获得x个随机数
  2. mn之间选择一个随机的p 将其保存到答案数组。 当我们得到问题的一个答案时,将x1
  3. 现在取qmp-1之间的随机数,再取rp + 1n之间的随机数。 填满答案阵列与质量可靠性降低X 1为q和另一个1 第r。
  4. 现在,递归进行此过程,直到下界( m )和上限( n )相等或x变为0为止。

好处:这种方法的好处是,在最坏的情况下,运行时将是O( x ),其中x是所需的随机数。 最好的情况censn也为o( x ),因为我必须找到至少n个随机数。 这两个组成了θ( x )复杂度的平均情况。

import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();

    public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
    {
        int randomNumbers[] = new int[howMany]; 
        GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
        return randomNumbers;
    }

    private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
    {
        if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
        {
            return ;
        }

    int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
    storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
    GenerateDistinctRandom.alreadyPut++;

    //calling the left side of the recursion
    recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
    recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);     
    }

    public static void main(String []args){
        int howMany = 5;
        int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);

        for(int i = 0;i < howMany;i++)
        {
            System.out.println(distinctNumber[i]);
        }

    }
}

这个怎么样?

package com.se;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TestRandom {

    List<Integer> comp = new ArrayList<>();
    int listSize = 20;
    public void doTask() {

        Random ran = new Random();
        int i = 0;
        while(i < listSize){
            int randomNumber = ran.nextInt(80) + 1;

            if(!comp.contains(randomNumber)){
               comp.add(randomNumber);
               i++;
            }
        }

    for(Integer num : comp){
        System.out.println(num);
    }
}

public static void main(String[] args) {
    TestRandom testRandom = new TestRandom();
    testRandom.doTask();
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM