練習問題

ここに挙げている問題では配列の使用は mainメソッドの引数として与えられた変数 argsのみとし, その他は,List (ArrayListもしくはLinkedList)を使用してください.argsを 受け渡す分には配列を使って構いませんが,新たに配列を作成しないようにしてください.

1. 乱数値100個の統計

0以上,1000未満の乱数を100個取得してください. それらの合計値,最大値,最小値,平均を求めてください. 出力は,まず,合計,最大値,最小値,平均を1行で出力してください. その次に,得られた乱数値を出力してください.ただし,10個出力するごとに改行を入れてください. クラス名は,StatsValues としてください.

平均をDouble型として求めるには,Integer型の合計値sumDouble型に変換する必要があります. Double.valueOf(sum)Double型に変換でき,それ以降Double型として扱えるようになります.

整数乱数を生成する

0以上,1000未満の乱数値を取得するには,Random型を利用します.Random型の 利用には,import java.util.Randomがクラス宣言の前に必要です. 以下のコードで1000未満の正数乱数が得られます.

なお,Random型の初期化は最初に1度だけ行うようにしてください. 乱数を得るたびにRandom型を初期化すると乱数にならない場合があります.

Random random = new Random();
Integer randomValue = random.nextInt(1000);
    // => 0以上1000未満の正の乱数値が得られる.

出力例

乱数ですので,必ずしもこの通りの結果にはなりません.

$ java StatsValues
合計: 45262, 最大値: 995, 最小値: 11, 平均値: 452.620000
252  37 553 448 504 144 969 928 177 262 
836  15 198 496 650 977 102 630 348 351 
820  59 288 435 622 677 103 588 576 683 
916 138 154 528 179 411 578 740 715 372 
351 105  41 203 596 746 195 153 469 328 
166 189 754 862 541  84 165 428 567  76 
848 730 947 439 376 258 330 365 896 144 
688  27 380 573 377 752  19  70 965 605 
551 355 103 860 629 660 528 465 995 134 
154 574  11 763 268 443 723 872 233 674

2. 素数の一覧

コマンドライン引数で与えられた値までの素数を出力してください. なお,素数を10個出力するごとに改行を入れてください. クラス名は Primes とします. コマンドライン引数で値が指定されなかった場合は,200までの素数を求めましょう.

素数を求めるには,エラトステネスのふるいを使うと良いでしょう. 次の画像は,0以上100未満の素数を求める時のエラトステネスのふるいのアルゴリズムを表したものです. 順に最後まで繰り返して残った値が素数です. 画像をクリックすると順に素数ではない数値が消えてきます.参考にしてください.

エラトステネスのふるい

まず ArrayListに求めたい値だけ,素数であるフラグ(Boolean型を使えば良いでしょう)をあらかじめ追加しましょう. そして,そこから,素数でないものを順に除外して来ましょう. その後,素数のみを納める別のArrayListを作成し,素数フラグのリストを順に見て素数のリストに格納していきましょう. その素数リストを返すArrayList<Integer> generatePrimes(Integer max) メソッドを作成しましょう.

出力例

$ java Primes 
    2     3     5     7    11    13    17    19    23    29
   31    37    41    43    47    53    59    61    67    71
   73    79    83    89    97   101   103   107   109   113
  127   131   137   139   149   151   157   163   167   173
  179   181   191   193   197   199 
$ java Primes 59
    2     3     5     7    11    13    17    19    23    29
   31    37    41    43    47    53    59

ヒント

ArrayList<Integer> generatePrimes(Integer max){
  ArrayList<Boolean> primes = new ArrayList<>();
  for(Integer i = 0; i <= max; i++){
    primes.add(true); // 仮に全てのiが素数であるとする.
  }
  primes.set(0, false); // 0は素数ではない.
  primes.set(1, false); // 1は素数ではない.

  for(Integer i = 2; i < primes.size(); i++){ 
        // 最小の値である2から始める.
    if(!primes.get(i)){ // iが素数ではなかったら何も行わない.
      continue;
    }
    // j = i * 2 から始めて j += i のインデックスを false にする.
  }
  return primesList(primes);
}
ArrayList<Integer> primesList(ArrayList<Boolean> primes){
  ArrayList<Integer> returnList = new ArrayList<>();
  for(Integer i = 2; i < primes.size(); i++){
    if(primes.get(i)){ // 素数なら returnList に追加する.
      returnList.add(i);
    }
  }
  return returnList;
}

3. 素因数分解

コマンドライン引数で与えられた整数値の素因数分解を行ってください. クラス名は,Factorizerとしてください.

素因数分解を行うには,素数で割り切れなくなるまで,その素数を素因数として記録します. そして,次の小さな素数で同じことを繰り返します.

  • 例えば,12 を素因数分解するとき,一番小さな素数である2で割り切れるかを確認します.
  • 1回目は割り切れ,2を素因数に追加し,割った後の数は6です.
  • 次に,62で割り切れます.再度,素因数に2 を追加します.割った後の数は3です.
  • 32では割り切れませんので,次の小さな素数で割り切れるかを確認します.
  • 33で割り切れますので,素因数として3を追加します.割った後の数は1ですので,これで終了です.

素数のリストを得るには,素数の一覧で作成した PrimesgeneratePrimes メソッドを 利用すれば良いでしょう.Primes.javaFactorizer.javaを同じディレクトリに置いてください. 先ほどの練習問題で適切にプログラムが書けていれば,次のプログラムで100までの素数の一覧が取得できます.

Primes primes = new Primes();
ArrayList<Integer> list = primes.generatePrimes(100);

出力例

$ java Factorizer 12
   12: 2 x 2 x 3
$ java Factorizer 24 50
   24: 2 x 2 x 2 x 3
   50: 2 x 5 x 5
$ java Factorizer 123 127
  123: 3 x 41
  127: 127

4. 試験成績の分析

import java.util.Random;
public class ExamAnalyzer{
  ExamScore createRandomScore(String name){
    Random random = new Random();
    Integer math = random.nextInt(101);
    Integer physics = random.nextInt(101);
    Integer english = random.nextInt(101);
    return this.createExamScore(math, physics, english, name);
  }
}

上記のプログラムを踏まえて,以下のプログラムを作成してください.

  1. ExamScore型を作成してください.
    • Integer型のmath
    • Integer型のphysics
    • Integer型のenglish
    • String型のnameをフィールドに持ちます.
  2. ExamAnalyzerに次のメソッド,処理を追加してください.
    • runメソッドを作成してください.引数,返り値はなしで構いません.
    • 3つのInteger型,1つのString型を受け取り,ExamScoreを返す createExamScoreメソッドを定義してください.
      • メソッドのボディで,ExamScoreの実体を作成し,引数の値を作成したExamScoreの実体のフィールドに代入してください.
      • 代入が終了した ExamScoreの実体を返してください.
    • runメソッド内で次の処理を行ってください.
      • ExamScore型の実体を格納するArrayList実体を作成してください.
      • createRandomScoreメソッドを用いて,ランダムな成績を10個作成してください.
        • 名前は数値の連番("0""9")にしましょう.
        • Integer型変数intValueString型に変換するには,"" + intValueもしくは,intValue.toString()としてください.
      • 作成したArrayListに上記で作成したランダムな成績を追加してください.
      • 全員のmathphysicsenglishごとに平均値,最大値,最小値を求めてください.
      • それぞれExamScoreの実体に対して,mathphysicsenglishの平均値を求めてください.
      • 求めた値を出力してください.

出力例

$ java ExamAnalyzer
       math   phys   eng    ave
ave   51.200 53.100 52.500
max       81     75     99
min       26      0      3
  0       72     53     11 45.333
  1       36     71     65 57.333
  2       33     26      3 20.667
  3       81      0     99 60.000
  4       42     75     36 51.000
  5       26     40     13 26.333
  6       64     57     55 58.667
  7       43     66     90 66.333
  8       50     72     84 68.667
  9       65     71     69 68.333

上記のように Double型の小数点を整形して出力するには,System.out.printf の フォーマット指定を%6.3fとしてください.%6.3f6が 全ての桁数の指定,.3が小数点以下の桁数を指定しています.