Рандомизация текстового файла, читаемого на Java

Я пытаюсь прочитать текстовый файл на Java, в основном набор вопросов. С четырьмя вариантами и одним ответом. Структура выглядит так:

вопрос

вариант a

вариант b

вариант c

вариант d

ответ

у меня нет проблем с чтением его таким образом:

public class rar{
public static String[] q=new String[50];
public static String[] a=new String[50];
public static String[] b=new String[50];
public static String[] c=new String[50];
public static String[] d=new String[50];
public static char[] ans=new char[50];
public static Scanner sr= new Scanner(System.in);


public static void main(String args[]){
int score=0;
try {
             FileReader fr;
      fr = new FileReader (new File("F:questions.txt"));
      BufferedReader br = new BufferedReader (fr);
int ar=0;
      for(ar=0;ar<2;ar++){
      q[ar]=br.readLine();
      a[ar]=br.readLine();
      b[ar]=br.readLine();
      c[ar]=br.readLine();
      d[ar]=br.readLine();
    String tempo=br.readLine();
    ans[ar]=tempo.charAt(0);






        System.out.println(q[ar]);
        System.out.println(a[ar]);
        System.out.println(b[ar]);
        System.out.println(c[ar]);
        System.out.println(d[ar]);
        System.out.println("Answer: ");
        String strans=sr.nextLine();
char y=strans.charAt(0);
if(y==ans[ar]){
    System.out.println("check!");
score++;
System.out.println("Score:" + score);
}else{
System.out.println("Wrong!");
}

      }
      br.close();
    } catch (Exception e) { e.printStackTrace();}


}




}

код выше предсказуем. Цикл for просто увеличивается. И это отображает вопросы по порядку.

то, что я хочу сделать, это иметь возможность рандомизировать текстовый файл, но все еще сохраняя ту же структуру. (q, a, b, c, d, ans). Но когда я пытаюсь это сделать:

int ran= random(1,25);
   System.out.println(q[ran]);
        System.out.println(a[ran]);
        System.out.println(b[ran]);
        System.out.println(c[ran]);
        System.out.println(d[ran]);
        System.out.println("Answer: ");
        String strans=sr.nextLine();
char y=strans.charAt(0);
if(y==ans[ran]){
    System.out.println("check!");
score++;
System.out.println("Score:" + score);
}else{
System.out.println("Wrong!");
}

и это метод, который я использую для рандомизации:

public static int random(int min, int max){
    int xx;
    xx= (int) ( Math.random() * (max-min + 1))+ min;
    return xx;
    }

есть вероятность, что я получу null. Что вы можете порекомендовать мне сделать, чтобы я не получал null при попытке рандомизировать вопросы?

вы видите что-нибудь еще не так с моей программой?

4 ответов


вы используете все виды магия чисел, числа в вашем коде, которые не имеют большого смысла.

public static String[] q=new String[50]; //why make an array to hold 50 questions?

//... 

for(ar=0;ar<2;ar++){ //why read 2 questions?

//...

int ran= random(1,25); //why take one of 25 questions?
System.out.println(q[ran]);

Это должно быть одно и то же число, верно? Если у нас есть 25 вопросов, у нас должно быть место для 25, прочитайте 25 и используйте 25.

как это исправить:

1 постоянно

public final static int NUMBER_OF_QUESTIONS = 25;

затем используйте это при создании массива, чтении вопросов и при принятии случайного:

public static String[] q=new String[NUMBER_OF_QUESTIONS];

for(ar=0;ar<NUMBER_OF_QUESTIONS;ar++){

int ran= random(1,NUMBER_OF_QUESTIONS);

2 Использовать вопрос.длина

public static String[] q=new String[NUMBER_OF_QUESTIONS];

for(ar=0;ar<q.length;ar++){

int ran= random(1,q.length);

3 Используйте список / коллекцию

public static List<String> q=new List<String>();

for(ar=0;ar<q.size();ar++){

int ran= random(1,q.size());

Вариант 3 был бы лучшим выбором, это java в конце концов. Майк отвечу более подробно в этой Java.


Я думаю, что небольшие структурные изменения очень помогут и сделают это намного проще для вас. Определение новых классов:Question и Answer. Пусть Question есть варианты и Answer внутри него. Это композиция объекта.

посмотреть в коллекция API. С коллекцией вопросов вы можете использовать метод shuffle для рандомизации их в одной строке. Пусть Java сделает работу за вас.

так что:

Collection<Question> questions = new ArrayList<Question>();

questions.add(...);
questions.add(...);
questions.add(...);

questions.shuffle();

немного приукрасить подробнее о том, почему вы хотите сделать это именно поэтому... Вы хотите отделить свой проблемы лучшее, что вы можете. Вопросы, ответы и варианты-все это разные проблемы. Ответ пользователя вызывает беспокойство. Рандомизация вопросов вызывает озабоченность. Реакция на ответ пользователя вызывает беспокойство.

будучи хорошим разработчиком программного обеспечения, вы захотите разделить все эти вещи. Конструкция Java для выполнения этого является классом. Вы можете развиваться ваши идеи относительно независимы внутри собственного класса. Когда вы удовлетворены своими классами, все, что вам нужно сделать, это подключить их. Определите их интерфейсы, как они разговаривают друг с другом. Мне нравится сначала определять интерфейсы, но когда я начинал, мне было немного легче беспокоиться об этом позже.

может показаться, что много работы, со всеми этими классами и интерфейсами, а что нет. Это займет меньше времени, чтобы сделать это таким образом, когда вы получаете хороший. И ваша награда-возможность повторного использования.


другие люди (Майк, Эрик) уже предложили лучшие подходы к этой проблеме, создав новый Question класс, добавление вопросов в коллекцию и использование shuffle метод рандомизации их.

относительно того, почему вы "получаете null" в своем коде: насколько я вижу в вашем примере кода, Вы читаете только два вопроса из файла:

for (ar=0;ar<2;ar++) {
    [...]
}

это означает, что позиции 0 и 1 в ваших массивах будут иметь действительные данные, в то время как позиции 2 до 49 будут contain null.

позже, когда вы пытаетесь рандомизировать вопросы, которые вы называете своим random способ такой:

int ran = random(1,25);

это возвращает значение от 1 до 25, которое затем используется в качестве индекса массива.

если этот индекс окажется "1", Вы будете в порядке. Для всех остальных случаев (от 2 до 25) вы будете получать доступ null значения в ваших массивах и получение исключений при попытке играть с этими значениями.


создайте класс для хранения вопроса и чтения файла в массив этих объектов.

разбейте проблему на три этапа. Первый шаг-прочитать в файле данных и сохранить все данные в объектах. Второй шаг-рандомизировать порядок этих объектов. Последний шаг-распечатать их.

ArrayList questions = new ArrayList();
for(ar=0;ar<2;ar++){
  q=br.readLine();
  a=br.readLine();
  b=br.readLine();
  c=br.readLine();
  d=br.readLine();
  String tempo=br.readLine();
  ans=tempo.charAt(0);

  questions.add(new Question(q, a, b, c, d, ans));
}

случайный массив такой:

Collections.shuffle(questions);

тогда просто цикл через вопросы и выход их.

for (Question q: questions) {
  q.write();
  System.out.println(); // space between questions
}

создайте такой класс вопросов, чтобы хранить ваши данные:

public class Question {
  private String question;
  private String option1;
  private String option2;
  private String option3;
  private String option4;
  private String answer;

  public Question(String question, String option1, String option2, String option3,
                  String option4, String answer) {
    this.question = question;
    this.option1 = option1;
    this.option2 = option2;
    this.option3 = option3;
    this.option4 = option4;
    this.answer = answer;
  }

  public void write() {
    System.out.println(this.question);
    System.out.println(this.option1);
    System.out.println(this.option2);
    System.out.println(this.option3);
    System.out.println(this.option4);
    System.out.println("Answer: "+this.answer);
  }
}