从一系列数字生成一组2个非重复随机数时出现Stackoverflow错误

时间:2017-06-05 14:04:59

标签: java android random stack-overflow

以下是我用来从一系列数字生成随机数的两种方法。这是小数学测验的一部分。问题的数量可以达到50个问题。唯一的条款是数字应该不重复,即如果列表中存在5x6,则列表中不能有6x5。

我面临的问题是下面的代码抛出stackoverflow错误。我试图在一个单独的线程中运行它,但我无法让它工作。

第一种方法中使用的for循环是我用来检查数字是否已存在的方法。

public QuestionsV1 generateQuestionsArray(int level, int range) {
generateRandomNumbers(level, range);
    for (QuestionsV1 questions : questionsList) {
        if (questionsList != null && ((first_number == questions.getFirst_number() && second_number == questions.getSecond_number())
                || (first_number == questions.getSecond_number() &&
                second_number == questions.getFirst_number()))) {
            generateQuestionsArray(level, range);
            break;
        }
    }
    Log.d("ArrayList---", first_number + " " + second_number);
    QuestionsV1 questions = new QuestionsV1();
    questions.setFirst_number(first_number);
    questions.setSecond_number(second_number);
    questions.setOperator("x");
    questions.setCorrect_answer(first_number * second_number);
    return questions;
}


public void generateRandomNumbers(int level, int range) {
    Random rand1 = new Random();
    Random rand2 = new Random();
    if (range == 0) {
        first_number = rand1.nextInt(3 - 1 + 1) + 1;
    } else if (range == 1) {
        first_number = rand1.nextInt(6 - 4 + 1) + 4;
    } else if (range == 2) {
        first_number = rand1.nextInt(10 - 7 + 1) + 7;
    }
    switch (level) {
        case 1:
            second_number = rand2.nextInt(6 - 2 + 1) + 2;
            break;
        case 2:
            second_number = rand2.nextInt(12 - 7 + 1) + 7;
            break;
        case 3:
            second_number = rand2.nextInt(20 - 13 + 1) + 13;
            break;

    }

以下是我得到的错误。

   Fatal Exception: java.lang.StackOverflowError: stack size 2MB
   at java.util.concurrent.atomic.AtomicLong.<init>(AtomicLong.java:61)
   at java.util.Random.<init>(Random.java:137)
   at java.util.Random.<init>(Random.java:105)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:80)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbers(Multiply.java:106)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateQuestionsArray(Multiply.java:39)
   at com.leapscale.scimat.t4e.Builders.Multiply.generateRandomNumbersHard(Multiply.java:74)
   at com.leapscale.scimat.t4e.Builders.Multiply.calculateNoOfQuestionsForLevels(Multiply.java:141)
   at com.leapscale.scimat.t4e.Builders.Multiply.getList(Multiply.java:146)
   at com.leapscale.scimat.t4e.Levels.Levels_Fragment$QuestionBuilder$1.run(Levels_Fragment.java:185)
   at java.lang.Thread.run(Thread.java:761)

1 个答案:

答案 0 :(得分:0)

使用while循环来保持生成,直到创建非重复值,而不是使用递归调用。类似的东西:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class App {
    private static final int QUESTION_COUNT = 25;
    private static final int RANGE = 10;
    private static final Random RAND = new Random();

    public static void main(String[] args) {
        App app = new App();
        app.generateAndDisplayQuestions();
    }

    private void generateAndDisplayQuestions() {
        List<QuestionV1> questions = new ArrayList<>();
        for (int q = 0; q < QUESTION_COUNT; q++) {
            while(true) {
                QuestionV1 question = getNextRandomQuestion();
                if (!questions.contains(question)) {
                    questions.add(question);
                    break;
                }
                System.out.println("found a duplicate - trying again...");
            }

            System.out.println("Question " + (q + 1) + ": first = " + questions.get(q).getFirst() + " : second = " + questions.get(q).getSecond());
        }
    }

    private QuestionV1 getNextRandomQuestion() {
        return new QuestionV1(RAND.nextInt(RANGE), RAND.nextInt(RANGE));
    }

    private class QuestionV1 {
        private int first;
        private int second;

        public QuestionV1(int first, int second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object o) {
            QuestionV1 other = (QuestionV1)o;
            return (this.first == other.first && this.second == other.second) || (this.first == other.second && this.second == other.first);
        }

        @Override
        public int hashCode() {
            return first * 31 + second;
        }

        public int getFirst() {
            return first;
        }

        public int getSecond() {
            return second;
        }

    }

}

如果RANGE为低且QUESTION_COUNT为高,那么这将导致无限循环,因为将使用所有可能的组合。