打印范围内的非重复随机数

时间:2019-08-11 02:50:38

标签: java random set

我正在尝试编写一个简单的随机数生成器类,该类将在给定的最大和最小范围内打印不重复的数字。我的逻辑全部消失了,我也在使用一组,但是我仍然得到一些重复的数字。这个想法是,如果我声明min和max为0和5,我应该得到2 3 1 5 4 0这样的随机数。然后它可以重置并在不重复的范围内再次给我随机数。参见下面的代码

package RandomNumberGen;

import java.util.*;
public class RandomNumberGenerator {

Random random = new Random();
int minimum;
int maximum;

Set<Integer> hSet = new HashSet<>(range);

public RandomNumberGenerator(int min, int max)
{
    minimum =  min;
    maximum = max;
}

public void generateRandomNumbers()
{
    int range =  maximum - minimum + 1; 
    int randomValue = 0; 

    if(shouldReset())
    {
        hSet.clear();
    }

    do
    {
        randomValue =  minimum + random.nextInt(range); 
    } while(!hSet.add(randomValue));

    System.out.println("The next random number is: " + randomValue);  

}

public boolean shouldReset()
{
    return hSet.size() >= maximum - minimum + 1;
}


public static void main(String[] args) 
{
    RandomNumberGenerator rng = new RandomNumberGenerator(1,10);
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();

    System.out.println("Should restart now");

    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
    rng.generateRandomNumbers();
}

}

当前在我的输出中,尽管使用HashSet删除了不重复的整数,我还是得到了这个:我期望像10 8 7 5 9 6这样的东西,但是我得到了

下一个随机数是:9

下一个随机数是:6

下一个随机数是:8

下一个随机数是:9

下一个随机数是:6

下一个随机数是:8

2 个答案:

答案 0 :(得分:1)

当前,您的设备并没有采取任何措施来防止重复。您应该将集合声明为字段,而不是局部变量。该集合实质上跟踪已生成的数字。

public class RandomNumberGenerator {

    private int minimum;
    private int maximum;
    private Random random = new Random();
    private Set<Integer> hSet =  new HashSet<>();

    public RandomNumberGenerator(int min, int max)
    {
        minimum = min;
        maximum = max;
    }

    public void printRandomNumber()
    {
        int range =  maximum - minimum + 1; 
        int randomValue = 0; 

        do
        {
            randomValue =  minimum + random.nextInt(maximum - minimum + 1); 
        } while(!hSet.add(randomValue));

        System.out.println("The next random number is: " + randomValue);    
    }
}

您还应该添加一个方法调用shouldReset来指示是否生成了所有数字:

public boolean shouldReset() {
    return hSet.size() >= maximum - minimum + 1; 
}

reset方法:

public void reset() {
    hSet.clear();
}

执行此操作的另一种方法是对所有可用数字的列表进行混洗,并按顺序返回经过混洗的列表中的元素:

public class RandomNumberGenerator {

    private int minimum;
    private int maximum;
    private Iterator<Integer> iter;

    public RandomNumberGenerator(int min, int max) {
        minimum = min;
        maximum = max;
        reset();
    }

    public void printRandomNumber() {

        System.out.println("The next random number is: " + iter.next());
    }

    public boolean shouldReset() {
        return !iter.hasNext();
    }

    public void reset() {
        List<Integer> list = new ArrayList<>(IntStream.rangeClosed(min, max).boxed().collect(Collectors.toList()));
        Collections.shuffle(list);
        iter = list.iterator();
    }
}

答案 1 :(得分:0)

由于Set<Integer> hSet = new HashSet<>();是在printRandomNumber函数中本地声明的,因此每次调用此函数时都会重新创建它,因此它永远不会跟踪以前存储的内容。

如果您希望它在所有对printRandomNumber的调用中保持不变,则可以将其设置为全局变量。