在Java中随机读取文本文件

6

我将尝试在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;
    }

可能会出现空值的情况。您有什么建议,让我在随机问题时不会得到空值?

您是否看到其他程序存在的问题?


Mike和Erick在这个案例中提出了很好的建议。虽然你的代码是合法的Java,但它看起来并不像Java。它更像是Pascal或其他使用Java语法编写的命令式语言。(当然可以编译和运行,但并没有充分利用你面前的工具)。 - Andrzej Doyle
4个回答

4
我认为稍微结构上的改变可以极大地帮助你,使得这个更容易。定义新类:QuestionAnswer。让 Question 拥有选项,并将 Answer 嵌入其中。这就是对象组合。
查看Collection API。通过一个问题集合,您可以使用 shuffle 方法在一行内随机排列它们。让Java替您处理工作。
所以,您可能会有:
Collection<Question> questions = new ArrayList<Question>();

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

questions.shuffle();

为了更好地区分你的关注点,你需要这样做。问题、答案和选项都是不同的关注点。用户的响应是一个关注点。问题的随机性是一个关注点。对用户响应的回应是一个关注点。
作为一名优秀的软件开发者,你需要将所有这些事情分门别类。Java的构造可以实现这一点,那就是类。你可以在自己的类中相对独立地开发自己的想法。当你满意于你的类时,你只需要连接它们。定义它们的接口,以及它们如何相互通信。我喜欢先定义接口,但当我开始时,我发现稍后再考虑这个问题会更容易一些。
可能看起来很麻烦,有这么多的类和接口等等。但当你变得熟练后,用这种方式花费的时间只是一小部分。而你的回报是可测试性和可重用性。

好的回答,特别是在给出背后的推理方面。 - Andrzej Doyle

2
其他人(Mike,Erick)已经提出了更好的解决方案来创建一个新的Question类,将问题添加到集合中并使用shuffle方法对它们进行随机排序,帮助解决这个问题。
关于为什么你的代码中“得到null”的问题:据我所见,在你的示例代码中,你只从文件中读取了两个问题。
for (ar=0;ar<2;ar++) {
    [...]
}

这意味着数组中的位置0和1将有有效数据,而位置2到49将包含null

稍后当您尝试随机化问题时,可以像这样调用random方法:

int ran = random(1,25);

这将返回1到25之间的一个值,您可以将其用作数组索引。

如果此索引恰好为'1',则一切都会很好。对于其他情况(2到25),您将访问数组中的null值,并在尝试操作这些值时出现异常。


2
你在代码中使用了各种 魔法数字,这些数字并没有太多意义。
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 使用 q.length

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。请参考Mike的答案,以获取更多有关如何使其更具Java特色的详细信息。

这是分配的正确方式吗?q[ran]=br.readLine();因为我没有得到一个随机问题。我按照您的回答中的选项1和2进行了操作。 - user225269

1

创建一个类来保存问题,并将文件读入这些对象的数组中。

将问题分解为三个步骤。第一步是读取数据文件并将所有数据存储在对象中。第二步是随机化这些对象的顺序。最后一步是将它们打印出来。

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(); // 问题之间的空格
}

创建一个像这样的问题类来保存你的数据:

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("答案:" + this.answer); } }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接