6

基本的に一連の質問であるJavaのテキストファイルを読み込もうとしています。選択肢は 4 つ、答えは 1 つです。構造は次のようになります。

質問

オプション 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

4 に答える 4

4

少しの構造上の変更が大いに役立ち、これがはるかに簡単になると思います。新しいクラスを定義します:QuestionAnswer. Questionオプションとその中に入れましょうAnswer。それがオブジェクト合成です。

Collection APIを調べてください。質問のコレクションでは、シャッフル メソッドを使用して、それらを 1 行でランダム化できます。Java に任せてください。

だからあなたは持っているかもしれません:

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

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

questions.shuffle();

なぜそれをしたいのかについてもう少し装飾するために、なぜこれが... あなたは自分の懸念をできる限り分離したいと考えています。質問、回答、オプションはすべて異なる問題です。ユーザーの反応が気になります。質問のランダム化は懸念事項です。ユーザーの反応に対する反応が気になります。

優れたソフトウェア開発者であれば、これらすべてを区分化する必要があります。これを実現するための Java の構造はクラスです。独自のクラス内で比較的独立してアイデアを開発できます。クラスに満足したら、あとはクラスを接続するだけです。インターフェイスを定義し、相互に対話する方法を定義します。私は最初にインターフェイスを定義するのが好きですが、始めたときは、後でそれについて心配する方が少し簡単であることに気付きました。

これらのすべてのクラスとインターフェイス、およびその他のものを使用すると、大変な作業のように思えるかもしれません。上手になると、この方法でそれを行うのに数分の一の時間がかかります。そして、あなたの見返りは、テスタビリティの再利用性です。

于 2010-10-08T11:54:50.277 に答える
2

他の人 (Mike、Erick) は、新しいQuestionクラスを作成し、コレクションに質問を追加し、shuffleメソッドを使用してそれらをランダム化することにより、この問題に対するより良いアプローチを既に提案しています。

コードで「nullを取得している」理由について:サンプルコードでわかる限り、ファイルから2つの質問しか読んでいません:

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

つまり、配列の位置 0 と 1 には有効なデータが含まれ、位置 2 から 49 にはnull.

random後で質問をランダム化しようとすると、次のようにメソッドを呼び出します。

int ran = random(1,25);

これは 1 から 25 までの値を返し、これを配列インデックスとして使用します。

このインデックスがたまたま「1」の場合は問題ありません。他のすべてのケース (2 から 25)nullでは、配列内の値にアクセスし、これらの値を操作しようとすると例外が発生します。

于 2010-10-08T12:44:28.600 に答える
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 です。これをより Java にする方法の詳細については、Mike の回答を参照してください。

于 2010-10-08T14:12:02.430 に答える
1

質問を保持するクラスを作成し、ファイルをこれらのオブジェクトの配列に読み込みます。

問題を 3 つのステップに分けます。最初のステップは、データ ファイルを読み込み、すべてのデータをオブジェクトに格納することです。2 番目のステップは、これらのオブジェクトの順序をランダム化することです。最後のステップは、それらを印刷することです。

ArrayList の質問 = 新しい ArrayList();
for(ar=0;ar<2;ar++){
  q=br.readLine();
  a=br.readLine();
  b=br.readLine();
  c=br.readLine();
  d=br.readLine();
  文字列 tempo=br.readLine();
  ans=tempo.charAt(0);

  question.add(新しい質問(q、a、b、c、d、ans));
}

次のように配列をランダム化します。

Collections.shuffle(質問);

次に、質問をループして出力します。

for (質問 q: 質問) {
  q.write();
  System.out.println(); // 質問間のスペース
}

データを保持するために、次のような質問クラスを作成します。

公開クラス 質問 {
  プライベート文字列の質問;
  プライベート文字列オプション 1;
  プライベート文字列オプション 2;
  プライベート文字列オプション 3;
  プライベート文字列オプション 4;
  プライベート文字列の回答。

  public Question(文字列の質問、文字列のオプション 1、文字列のオプション 2、文字列のオプション 3、
                  文字列オプション 4、文字列回答) {
    this.question = 質問;
    this.option1 = オプション 1;
    this.option2 = オプション 2;
    this.option3 = option3;
    this.option4 = option4;
    this.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);
  }
}
于 2010-10-08T11:58:49.607 に答える