復習課題:素数を題材にアルゴリズムを考えながらループや配列を扱う

課題 1:入力された値が素数か否かを判定する

単純に入力した数値ひとつを素数か否か判定するプログラムを作ります。

実行例(赤文字は入力を意味する):
$ ./a.out 
13
13 is PRIME
$ ./a.out 
12
12 is NOT PRIME
$

入力した値(仮に x とします)を、2 から x-1 までの数で片っ端から試し割りして、もし一つでも割りきれた場合、x は素数ではない、とは判定できます。 プログラムとしてもそのように書けばできるはずです。 「素数ではない」と判定できたときにすぐ「is not PRIME」、と出力しても良いのですが、プログラムとしては「素数ではない」ことを意味するフラグを立てて、ループから抜けた後にフラグ判定して「is PRIME」「is NOT PRIME」のいずれを出力すべきかを選択するほうが賢明です。


課題 2:くり返して処理できるようにする(素数のものには目印を付けて表示)

最大・最小の数を調べたときのように、いちいちキー入力せず、リダイレクションによってファイルから入力することにします。くり返しは 6 件です。 入力したものを表示して、素数には PRIME と目印を付けて表示するようにします。

実行例(赤文字は入力を意味する):
$ ./a.out < testdata.txt
  8
 93
 42
  7 (PRIME)
 92
 79 (PRIME)
$

この段階では入力を配列に入れる必要はありません。先の課題のプログラムをループさせるだけで処理可能です。 なお出力結果の数値が右揃えになるように printf の変換文字を調整すること。


課題 3:配列に保存する

先の課題と同じ結果を出すだけですが、その次の課題に備えて入力データを配列に保持して処理するように変えてください。つまり最初に、以下のようにして配列に6件のデータを全部おさめてしまい、その後の判定・出力処理は別のループで行うようにします。

    for(j=0; j<NUM; j++) {
        scanf("%d", &data[j]);
    }
実行例(赤文字は入力を意味する):
$ ./a.out < testdata.txt
  8
 93
 42
  7 (PRIME)
 92
 79 (PRIME)
$

課題 4:素数と非素数を分けて表示する

先の課題とは出力形式が異なります。素数とそうでないものに分けて表示させます。

実行例(赤文字は入力を意味する):
$ ./a.out < testdata.txt
prime numbers
  7
 79
other else
  8
 93
 42
 92
$

これを実現するためには素数を配列に入れるだけでなく、素数であるか否かを判定した結果(フラグ)もやはり配列として保存する必要があるでしょう。 データとフラグをともに配列として一対一で用意してしまうのです。 処理としては以下のようになるでしょう。

  1. 配列にデータを入れる(scanf をループ)
  2. データを順繰りに素数判定し、結果をデータに対応するフラグに格納する
  3. 判定が終わったら、フラグを順繰りにチェックして、素数であるものだけを出力する
  4. 再びフラグを順繰りにチェックして、しかし今度は素数でないものだけを出力する