如何防止重叠的随机数

时间:2015-01-20 05:31:15

标签: java random

我如何防止从随机数中复制数字。 我需要在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);

8 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:6)

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

在填充集后,您有5个唯一的随机数。

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

答案 2 :(得分:1)

  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;
    }
    

答案 3 :(得分:1)

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

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。

答案 4 :(得分:1)

Floyd's subset selection algorithm旨在完全按照您的意愿行事,即使对于大型套装也非常有效。从一组m中选择n项是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;
}

答案 5 :(得分:0)

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

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;
    }
}

你可以继续制作类似的陈述。但是如果你应该知道数组,你肯定应该用一个来存储数字。

答案 6 :(得分:0)

解决这个问题的一种可能方法是划分&amp;征服。以下步骤描述了该方法:

  1. m 是最低&amp; n 是最大值,在我想要的 x 数量的randoms
  2. m &amp;之间选择一个随机的 p <强>名词即可。将其保存到答案数组中。当我们得到一个问题的答案时,将 x 减少 1
  3. 现在在 m &amp;之间取一个 q 随机数 p-1 ,另一个 r p + 1 之间的随机数&amp; <强>名词即可。使用 q &amp;和填写答案数组对于 q r 降低 x 1,对于 r 则降低<1>
  4. 现在递归地继续这个过程,直到下限( m )&amp;上限( n )变得相等或 x 变为 0
  5. 好处:这种方法的好处是,在最坏的情况下,它的运行时间为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]);
            }
    
        }
    }
    

答案 7 :(得分:0)

这个怎么样?

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();
}

}