简体   繁体   English

如何在JAVA中生成包括特定数字在内的不同随机数列表?

[英]How to generate a list of distinct random numbers including a specific number in JAVA?

Ok, so the scenario is, I want to generate a list of 4 distinct random numbers which will represent 4 random choices for a quiz application. 好的,所以场景是,我想生成一个包含4个distinct随机数的列表,这些列表将代表测验应用程序的4个随机选择。 One of the 4 random choices will be the correct answer, so we will already know the index of the correct choice. 四个随机选择之一将是正确的答案,因此我们将已经知道正确选择的索引。 This correct index or number must be included in the random number list. 此正确的索引或数字必须包含在随机数列表中。

For example: Consider that we have an array of length 100, containing string values representing 100 choices for a question, and the index of correct choice is 45 . 例如:考虑我们有一个长度为100的array ,其中包含代表一个问题的100个选择的string值,正确选择的index45 Now we want 4 random choices for this question including the index 45, so that the index list will be something like {2, 91, 45, 17}. 现在,我们需要为该问题提供4个随机选择,包括索引45,这样索引列表将类似于{2,91,45,17}。 Also the list shouldn't contain duplicate numbers. 此外,列表中不应包含重复的数字。

Any idea how to achieve this in Java ? 知道如何在Java中实现吗?

For Java 6 and newer: 对于Java 6及更高版本:

final int maxNumber = 100;
final int numbersToGenerate = 4;
final int correctAnswer = 45;

Set<Integer> possibleAnswers = new HashSet<>();
Random random = new Random();

// add correct answer
possibleAnswers.add(correctAnswer);

// add as much random answers as needed, the usage of a set prevents duplicates
while(possibleAnswers.size() < numbersToGenerate) {
    possibleAnswers.add(random.nextInt(maxNumber));
}

// convert set to list and shuffle it
List<Integer> answers = new ArrayList<Integer>(possibleAnswers);
Collections.shuffle(answers, new Random(System.nanoTime()));

For Java versions below 6 you have to write your own shuffle method, because Collections.shuffle was introduced in Java 6, as far as I know. 对于低于6的Java版本,您必须编写自己的shuffle方法,因为据我所知, Collections.shuffle是Java 6中引入的。

I first suggested to use the random api of Java 8, but found an bug in my idea. 我首先建议使用Java 8的随机api,但在我的想法中发现了一个错误。 If the array of generated random numbers contains the correct answer it will not work. 如果生成的随机数数组包含正确的答案,它将不起作用。 For your understanding: 您的理解:

NOT WORKING!!! 不工作!

final int minNumber = 1;
final int maxNumber = 100;
final int numbersToGenerate = 3;

final int[] ints = new Random().ints(minNumber, maxNumber)
.distinct().limit(numbersToGenerate).toArray();

List<Integer> possibleAnswers = asList(ints);
possibleAnswers.add(correctAnswerIndex);
Collections.shuffle(possibleAnswers, new Random(System.nanoTime()));

NOT WORKING !!! 不工作!

This class could help you 这节课可以帮助你

public class RandomQuiz {

    //The number of possible answers
    private int size;
    //The number of possible indexes
    private int n;
    //The correct index
    private int correct;

    //Constructor
    public RandomQuiz(int size, int n, int correct) {
        this.size = size;
        this.n = n;
        this.correct = correct;
    }

    //Returns size number of shuffled random indexes
    public int[] getRandomIndexes() {
        //The result set
        int[] result = new int[size];
        //We start with the correct index in the first place, so random values will be entered starting from the second place
        int index = 1;
        //First thing's first
        result[0] = correct;
        Random random;
        while (index < size) {
            //We always decrease the number of seeds
            random = new Random(n - index);
            //Getting a random value
            int randomized = random.nextInt();
            //Ensuring the numbers are not duplicate
            for (int i = 0; i < index; i++) if (randomized >= result[i]) randomized++;
            result[index++] = randomized;
        }
        //Randomize where correct will be at the end:
        random = new Random(size);
        int newIndex = random.getNextInt();
        //If the new index of correct is bigger than 0
        //than swap it with the item located on newIndex
        if (newIndex > 0) {
            result[0] = result[newIndex];
            result[newIndex] = correct;
        }
        return result;
    }
}

EDIT: 编辑:

In a private chat with Anton he told me that some parts are unclear, namely: 在与安东的私人聊天中,他告诉我有些地方不清楚,即:

  • why did I decrease the number of seeds 为什么我减少种子数量
  • why did I increase randomized in a cycle 为什么我会在一个周期内randomized增加

The number of seeds is decreased since we can use any number once maximum. 种子的数量减少了,因为我们最多可以使用任意数量的种子。 If the seed was 100, then after the first item was chosen, it becomes 99 and so on. 如果种子是100,则在选择第一个项目后,它变为99,依此类推。 To answer the second question: if 45 was chosen and then a number at least of 45 is chosen, then we need to add 1 to that number to cope with the gap left when we have chosen 45. If there were some numbers chosen and we choose a new number, then we need to add to that number the number of gaps below it, that is, the number of already chosen smaller or equal numbers to cope with all the gaps. 要回答第二个问题:如果选择了45,然后选择了至少为45的数字,那么我们需要在该数字上加1以应对选择45时剩下的差距。如果选择了一些数字,我们选择一个新的数字,然后我们需要在该数字下方添加空白数量,即已经选择的较小或相等数字的数量来应对所有空白。

Note that nothing was taken personally, I would leave the kind of comments I have left here if somebody else's correct answer was down-voted as well. 请注意,没有什么私人的事情,如果别人的正确答案也被否决,我将留下我留下的评论。 I am not against my answer being down-voted, but against down-voting correct answers in general. 我不是反对我的答案被否决,而是反对总体上否决正确答案。

I wrote a full program based on your needs. 我根据您的需要编写了完整的程序。 However please take a look at what I am doing. 但是,请看一下我在做什么。 With just a little context, this is what I created: 只需要一点上下文,这就是我创建的:

     // initialize a random object once.
     Random random = new Random();
     // the question
     String question = "With what letter does the name start of the new president of the USA?";
     // here are some basic answers
     String[] answers = new String[] {
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k"
     };
     // you already know the correct index of the array above, in this case it's d
     int index = 3;
     // this array will contain four answers, including correct one!
     String[] four = new String[4];
     // get answer index, we will place correct value in that index
     int answerIndex = random.nextInt(four.length);
     // now lets pick 4 answers!
     for (int i = 0; i < four.length; i++) {
      // we are at the answer index!
      if (i == answerIndex) {
       four[i] = answers[index];
       continue;
      }
      int randomIndex = random.nextInt(answers.length);
      for (int j = 0; j < four.length; j++) {
       // we got duplicate here!
       if (answers[randomIndex].equals(four[j])) {
        randomIndex = random.nextInt(answers.length);
        // redo this current iteration
        j = j - 1;
       }
      }
      four[i] = answers[randomIndex];
     }

Output: 输出:

e, c, d, h
g, d, d, h
d, g, e, f
d, f, b, i
g, d, a, b
c, d, g, b
h, d, e, k
e, f, d, c
k, d, e, h
i, d, e, d

It will help if you explain where you are using it for, as well as a short demonstration at what you have already coded. 如果您解释将在何处使用它,以及对已编码内容的简短演示,将很有帮助。

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

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