Переполнение стека на случайных целых числах - PullRequest
0 голосов
/ 19 сентября 2019

Там, где находится закомментированный раздел, написано, что есть StackOverflowError - null.Я пытаюсь заставить это сделать случайные числа, чтобы соответствовать с введенным значением.Целью этого кода является следующее:

  1. Примите верхнее число (т.е. 1000, чтобы иметь шкалу (1-1000)).
  2. Примите ввод в качестве числа, чтобы компьютер угадал.
  3. Компьютер случайным образом угадывает первое число и проверяет, правильно ли оно.
  4. Если это не правильно, он должен пройти через цикл и случайным образом угадывать числа, добавляя их в ArrayList, пока он не угадает ввод.Он должен проверить, находится ли предположение в массиве, и сгенерирует другое случайное число, пока оно не появится в списке, которого нет в списке.
  5. В конце он напечатает количество итераций с переменной count .

Код:

import java.util.*;

public class ArrNumGuess
{
    public static Integer top, input, guess, count;
    public static ArrayList <Integer> nums;
    public static void main ()
     {
        System.out.println("Please enter the top number");
        top = (new Scanner(System.in)).nextInt();
        System.out.println("Please enter the number to guess (1 - " + top + ")");
        input = Integer.parseInt(((new Scanner(System.in)).nextLine()).trim());
        nums = new ArrayList<Integer>(); //use nums.contains(guess);
        guess = (new Random()).nextInt(top) + 1;
        nums.add(guess);
        System.out.println("My first guess is " + guess);
        count = 1;
        if(guess != input)
        {
            guesser();
        }
        System.out.println("It took me " + count + " tries to find " + guess + " and " + input);
    }

    public static void guesser()
    {
         boolean check = false;
         while(!check)
        {
            guess = (new Random()).nextInt(top) + 1; //Stack Overflow - null
            if(nums.contains(guess) && !(guess.equals(input)))
            {
                count--;
                guesser();
            }
           else if(guess.equals(input))
           {
                check = true;
                System.out.println("My guess was " + guess);
                // nums.add(guess);
                count++;
            }
           else
           {
               System.out.println("My guess was " + guess);
                nums.add(guess);
                count++;
           }
        }
     }
 }

Ответы [ 3 ]

5 голосов
/ 19 сентября 2019

В методе guesser() вы вызываете себя:

if(nums.contains(guess) && !(guess.equals(input)))
{
    count--;
    guesser();
}

Вполне возможно, что он никогда не закончится.Но все это в цикле while, так почему бы не избавиться от повторения и сделать это в итеративном стиле?

0 голосов
/ 19 сентября 2019

ОК - другой подход к вашему guesser для развлечения.Перечислите случайную последовательность чисел в указанном диапазоне (от 1 до «сверху») и найдите guess в списке, индекс которого фактически равен числу «попыток» и возврата.

(BTW - @Andronicus answerправильный.)

/** Pass in 'guess' to find and 'top' limit of numbers and return number of guesses. */
public static int guesser(int guess, int top) {
    List<Integer> myNums;
    Collections.shuffle((myNums = IntStream.rangeClosed(1, top).boxed().collect(Collectors.toList())), new Random(System.currentTimeMillis()));        
    return myNums.indexOf(guess);
}
0 голосов
/ 19 сентября 2019

Вы делаете это более сложным, чем нужно, и вводите рекурсию без необходимости.Рекурсия является источником переполнения вашего стека, так как она становится слишком глубокой, прежде чем она «угадывает» правильно.Там тоже много разгильдяйства.Вот очищенная версия:

import java.util.*;

public class Guess {
    public static void main(String args[]) {
        System.out.println("Please enter the top number");
        Scanner scanner = new Scanner(System.in);
        int top = scanner.nextInt();
        System.out.println("Please enter the number to guess (1 - " + top + ")");
        int input = scanner.nextInt();
        if (input < 1 || input > top) {
            System.out.println("That's not in range. Aborting.");
            return;
        }

        ArrayList <Integer> nums = new ArrayList<>();

        Random rng = new Random(System.currentTimeMillis());
        while(true) {
          int guess = rng.nextInt(top) + 1;
          if (!nums.contains(guess)) {
            nums.add(guess);
            if (nums.size() == 1) {
                System.out.println("My first guess is " + guess);
            } else {
                System.out.println("My guess was " + guess);
            }
            if (guess == input) {
                System.out.println("It took me " + nums.size() + " tries to find " + guess);
                break;
            }
          }
        }
    }
}
...