前回小テストの解説

そもそもの問題はこうだった:
0 から 9 までの整数を 10個入力する. この中で, 出現回数がちょうど1回だった整数を小さい順から全て出力するプログラムを作成せよ.
まず, 最初のステップ. 処理全体は以下の3ステップになるだろう:
データを配列に読み込む 0 から 9 までの数値の出現回数をそれぞれ求める 出現回数がちょうど1回のものを小さい順に出力する
つぎに, これら3ステップをそれぞれ詳細化する:
データの番号 j を 0 から 9 まで変えながら 数値を一つ読み込み データ の j番目 ← 読み込んだ数値 数値 i を 0 から 9 まで変えながら i の出現回数をもとめる 数値 i を 0 から 9 まで変えながら i の出現回数が 1 ならば i を出力する
さらに, 第二ステップの「0 から 9 までの数値の出現回数をそれぞれ求める」ところはもう一段詳細化して, こうなる:
数値 i を 0 から 9 まで変えながら i の出現回数 ← 0 データの番号 j を 0 から 9 まで変えながら データ の j番目 が i だったら i の出現回数 ← i の出現回数 + 1
あとはこれをプログラムにする. 「データ」や「i の出現回数」は配列にする必要があることに注意し, 変数の宣言などを追加すれば完成する.
#include <stdio.h> int main(); int main(){ int i; int j; int data[10]; int occur[10]; char line[80]; for(j=0; j<10; j++){ gets(line); data[j] = atoi(line); } for(i=0; i<10; i++){ occur[i] = 0; for(j=0; j<10; j++){ if(data[j] == i){ occur[i] ++; } } } for(i=0; i<10; i++){ if(occur[i] == 1){ printf("%d\n", i); } } }
ここからはプログラムの改良. じつは, このプログラムにはまだまだ工夫の余地がある. 「0 から 9 までの数値の出現回数をそれぞれ求める」 の部分は二重のループ構造にしているが, 工夫すると一重ですむ. こんな感じ.
iの出現回数 をすべて 0 にする データの番号 j を 0 から 9 まで変えながら i ← データ の j番目 i の出現回数 ← i の出現回数 + 1
さらに, これの後の方のループはプログラム先頭のデータ読み込みのループと 統合できる. 処理全体はこんな感じになる.
数値 i を 0 から 9 まで変えながら i の出現回数 ← 0 データの番号 j を 0 から 9 まで変えながら 数値を一つ読み込み i ← 読み込んだ数値 i の出現回数 ← i の出現回数 + 1 数値 i を 0 から 9 まで変えながら i の出現回数が 1 ならば i を出力する
このやりかただと, 入力データを保存しておく配列 data が不要になる.
この手順を C のプログラムにして, 基礎プロくんの「課題1」として 実行してみよう.
[page 8] prev index next