如何在10到99之间生成50个随机数,没有重复。

时间:2014-02-10 07:01:21

标签: java

这是我解决问题的代码。但它似乎真的很粗暴。有没有优化/优雅的方式来写这个?

System.out.println("\n\nPart II: Let' put in a list of 50 random numbers between 10 to 99. No Duplicates!");

        Linkedlist l1 = new Linkedlist();
        Random rand = new Random(); 

        for(int i = 0; i < 50; i++){
            int num = rand.nextInt(89) + 10;//range between 10 and 99.
            while(true){
                if(!l1.search(num)){
                    l1.add(num);
                    break;
                }
                else
                    num = rand.nextInt(89) + 10;//recycle for new num 
            }//infinite loop until new non-duplicate random value is generated for the list. 

        }//for

6 个答案:

答案 0 :(得分:7)

有一种更清洁的方法可以做到这一点,不涉及随机化和输出拒绝。您可以使用所需的数字填充列表,在这种情况下:

List<Integer> numberList = new ArrayList<>();
for(int i=11; i<=99; i++){
    numberList.add(i);    
}

然后随机播放列表并从中挑选出前N个数字..

Collections.shuffle(numberList);
for(int j=0; j<50; j++){
    System.out.println(numberList.get(j));
}

你必须提前知道你的设置才能填充它。

答案 1 :(得分:5)

有界Fisher-Yates shuffle。随机采样的运行时间是您需要的元素数量的线性,而不是您从中挑选的元素数量。你不要浪费任何时间洗牌所有元素或拒绝已经被挑选的元素。

int[] sample(int sampleSize, int startInclusive, int endExclusive) {
    int[] samples = new int[sampleSize];
    int[] range = IntStream.range(startInclusive, endExclusive).toArray();
    Random random = new Random();
    for (int i = 0, j = range.length; i < samples.length; i++) {
        int k = random.nextInt(j--);
        samples[i] = range[k];
        range[k] = range[j];
    }
    return samples;
}

答案 2 :(得分:3)

我更希望使用Set代替List因为Set会自动处理重复项,因此我们需要担心我们自己将其删除。

试试这个:

    Set<Integer> set = new HashSet<Integer>();

    Random rand = new Random();

    while(true) {
        int num = rand.nextInt(89) + 10;// range between 10 and 99.
        set.add(num);
        if (set.size() == 50) {
            break;
        }
    }
    System.out.println(set);

答案 3 :(得分:2)

Sets不允许重复:

Set<Integer> s = new HashSet<Integer>();
Random rand = new Random();
while (s.size() < 50) {
    int num = rand.nextInt(89) + 10;// range between 10 and 99.
    s.add(num);
}

答案 4 :(得分:1)

您可以使用Set,只允许将唯一值存储在其中,这样您就可以保持循环,同时元素数量少于50 ...

Set<Integer> nums = new HashSet<>(50);
while (nums.size() < 50) {
    nums.add((int)(10 + (Math.random() * 89)));
}

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

这是对@ AnkurShanbhag的答案的一个变体(我不喜欢while (true)循环;)),所以如果你愿意,可以拍摄它们;)

答案 5 :(得分:0)

    package com.project.stackoverflow;

import java.util.Random;
import java.util.Scanner;
import java.util.TreeSet;

public class RandomGenerator {

    private Scanner s;

    public TreeSet<Integer> compute() {
        TreeSet<Integer> generatedList = new TreeSet<Integer>();
        s = new Scanner(System.in);
        System.out.println("Enter the lower bound for checking random numbers:");
        long lowBound = s.nextLong();
        System.out.println("Enter the upper bound for checking random numbers:");
        long topBound = s.nextLong();
        Random randomNumbers = new Random();
        for (int i = 0; i < topBound; i++) {
            if (generatedList.size() == 5) {
                break;
            } else {
                generatorFunc(lowBound, topBound, randomNumbers, generatedList);
            }
        }
        return generatedList;
    }

    public void generatorFunc(long lowBound, long topBound, Random randomNumbers, TreeSet<Integer> generatedList) {
        long limit = topBound - lowBound;
        long part = (long) (limit * randomNumbers.nextDouble());
        int randomNum = (int) (part + lowBound);
        generatedList.add(randomNum);
    }

    public void printList() {
        TreeSet<Integer> testListVals = compute();
        System.out.println("New" + testListVals);
    }

    public static void main(String[] args) {
        RandomGenerator obj = new RandomGenerator();
        obj.printList();
    }
}