Java 如何防止重叠的随机数

Java 如何防止重叠的随机数,java,random,Java,Random,如何防止从随机数中复制数字。 我需要生成5个介于1和9之间的数字,每个数字都不同。 我经常会得到像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

如何防止从随机数中复制数字。 我需要生成5个介于1和9之间的数字,每个数字都不同。 我经常会得到像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);
Set Set=newhashset();

而(set.size()一个选项是使用洗牌算法(例如)生成从1到9的随机序列,然后取序列的前5个数字


关于StackOverflow的进一步解释:

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

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;
} 
你可以继续这样做while语句,但是如果你应该知道数组,你肯定应该用数组来存储数字

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

    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;
    }
    
    publicstaticvoidmain(字符串[]args){
    int[]answers=返回随机非重复数(5,0,9);
    for(int答案:答案){
    System.out.println(应答);
    }
    }
    公共静态int[]returnRandomNonRepeatingNumber(int-sizeYouWant、int-poolStart、int-poolEnd){
    列表池=新的ArrayList();
    
    对于(int i=poolStart;i如果可能的随机值的数量很小,则需要使用shuffle

    List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
    Collections.shuffle(values);
    values = values.subList(0, 5);
    
    List values=IntStream.range(0,10).boxed().collect(toList());
    集合。洗牌(值);
    值=值。子列表(0,5);
    

    如果可能的随机值的数量很大,则需要测试将它们添加到集合(或原始列表,如果足够小)

    Set valueSet=new HashSet();
    Random rand=新的Random();
    而(valuesSet.size()<5)valuesSet.add(rand.nextInt(9)+1);
    列表值=新的ArrayList(值集);
    集合。洗牌(值,rand);
    

    注意:您需要对集合进行洗牌,因为它不会保持顺序。例如,数字1、2、3总是按照哈希集合的顺序出现,而不是3、2、1。

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

  • 假设m是最小值,n是最大值,在我想要得到的x随机数范围内
  • mn之间随机选择p。将其保存到一个答案数组中。当我们得到问题的一个答案时,将x减少1
  • 现在取一个q一个介于mp-1之间的随机数,另一个r一个介于p+1n之间的随机数。用qr减少x1填充答案数组qr
  • 现在递归地执行此过程,直到下限(m)和上限(n)相等或x变为0
  • 好处:这种方法的好处是,在最坏的情况下,它的运行时间将是O(x),其中x是所需的随机数。最佳情况下的场景也是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]);
            }
    
        }
    }
    
    import java.util.Random;
    类GeneratedStinctrandom{
    静态int alreadyPut=0;
    静态随机兰德=新随机();
    公共静态int[]generatedistincrandom(int多少,int最小范围,int最大范围)
    {
    int randomNumbers[]=新的int[多少];
    recursiveRandomGenerator(rangeMin、rangeMax、RandomNumber、HowNumber);
    返回随机数;
    }
    私有静态void recursiveRandomGenerator(int-rangeMin、int-rangeMax、int[]存储、int-storageSize)
    {
    if(rangeMax-rangeMin被设计为完全满足您的需求,即使对于大型集合也是非常有效的。从一组
    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;
    }
    
    /*
    *Floyd选择m个整数的随机子集的算法
    *从一组n开始,从零开始。
    */
    公共静态哈希集generateMfromN(int m,int n){
    HashSet s=新的HashSet();
    对于(int j=n-m;j
    这个怎么样

    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();
    }
    
    }
    
    package.com;
    导入java.util.ArrayList;
    导入java.util.List;
    导入java.util.Random;
    公共类TestRandom{
    List comp=new ArrayList();
    int listSize=20;
    公共void doTask(){
    Random ran=新的Random();
    int i=0;
    而(i
    添加到集合中。仅供参考:如果您的范围仅为1-9,则应使用随机数。很可能会出现重复。对于小范围集合,排列可能是最好的。对于大范围,您可以创建一组已选择的值,并根据需要重试。对于大范围,当需要有界最坏情况时行为,你需要在[1,m],[1,m-1],…[1,m-n+1]中选择n个不同的随机值,然后进行修复。你一定会喜欢最坏情况下复杂度为无限时间的解决方案:)@Kon发布你自己的答案。@JaredBurrows Phuong上面已经发布了
    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]);
            }
    
        }
    }
    
    /*
     * 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;
    }
    
    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();
    }
    
    }