2017-06-05 2 views
0

Voici les 2 méthodes que j'utilise pour générer un nombre aléatoire à partir d'une plage de nombres.Ceci fait partie d'un petit quiz mathématique. Le nombre de questions peut aller jusqu'à 50 questions. La seule clause est les numéros doivent être non répétés i.e 5x6 si est présent dans la liste je ne peux pas avoir 6x5 dans la liste. Le problème que je suis confronté est le code ci-dessous throws erreur stackoverflow.J'ai essayé de l'exécuter dans un thread séparé, mais je suis incapable de le faire fonctionner.Erreur Stackoverflow lors de la génération d'un ensemble de 2 nombres aléatoires non répétés à partir d'une plage de nombres

La boucle for utilisée à l'intérieur de la première méthode est celle que j'utilise pour vérifier si le nombre est déjà présent.

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; 

    } 

Ci-dessous est l'erreur que je reçois.

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

Vous ne voulez probablement pas appeler 'generateQuestionsArray (level, range);' à l'intérieur de lui-même avec exactement les mêmes arguments. C'est une récursion infinie de manuel. – khelwood

+0

désolé mon mauvais je l'ai édité .. s'il vous plaît vérifier –

+0

@ khelwood si je n'appelle pas alors je ne pourrai pas jeter le nombre actuellement généré –

Répondre

0

Au lieu d'utiliser appel récursif utiliser une boucle while pour continuer de produire jusqu'à ce qu'une valeur non dupliquée est créée. Quelque chose de semblable à ceci:

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

    } 

} 

pas que si RANGE est faible et QUESTION_COUNT est élevé, cela provoque une boucle infinie puisque toutes les combinaisons possibles seront utilisées.