今回は、配列の中身を調べるというテーマでプログラムを考えてみたいと思います。
すでに配列にデータが入っている状態を想定し、色々なプログラムを作ります。
では最初の問題です。
次のプログラムを見てください。
<sample program 065-00>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; /* ここにプログラムを追加 */ return 0; } |
このプログラムを改良し、配列内のデータで50以下のデータだけ表示するプログラムを作ってください。
<実行結果>
23 45 12 32 12 続行するには何かキーを押してください・・・
解答例です。
<sample program 065-01>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; for (i = 0; i < COUNT; i++) { if (data[i] <= 50) { printf("%d\n", data[i]); } } return 0; } |
<実行結果>
23 45 12 32 12 続行するには何かキーを押してください・・・
以前にも書きましたが、人間は「ぱっ」と見ればどれが50以下か判断できます。
しかし、コンピュータは1つ1つ調べないと判断できません。
ループの中でif文を使い、1つ1つ50以下かどうかを調べて表示するのです。
では、次に行ってみましょう。
今度は、配列dataの中に55があるかどうか調べ、もしあれば「発見!」と表示します。
先ほどのプログラムと同じく<sample program 065-00>を改良して作ってください。
<実行結果>
発見! 続行するには何かキーを押してください・・・
解答例です。
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; for (i = 0; i < COUNT; i++) { if (data[i] == 55) { printf("発見!\n"); } } return 0; } |
<実行結果>
発見! 続行するには何かキーを押してください・・・
これも55があるかどうかは人間であれば瞬時に判断できますが、コンピュータは1つずつ調べなければなりません。
少し改良すればできますので、そう難しくはないですね。
次へ進みましょう。
キーボードからデータを入力し、入力した値が配列dataの中にあれば「発見!」と表示します。
無かったら「発見できず・・・」と表示します。
これも<sample program 065-00>を改良して作ってください。
<実行結果>
探したいデータを入力してください:98 発見! 続行するには何かキーを押してください・・・
解答例の前に・・・
例えば98と入力した場合、このようになっていませんか?
<実行結果>
探したいデータを入力してください:98 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見! 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 続行するには何かキーを押してください・・・
これはプログラムが以下のようになってることが原因でしょう。
<sample program 065-03-1>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; int input; printf("探したいデータを入力してください:"); scanf("%d", &input); for (i = 0; i < COUNT; i++) { if (data[i] == input) { printf("発見!\n"); } else { printf("発見できず・・・\n"); } } return 0; } |
<実行結果>
探したいデータを入力してください:98 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見! 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 発見できず・・・ 続行するには何かキーを押してください・・・
この方法だと、値が違っていた場合はすべて「発見できず・・・」というメッセージが表示されてしまいます。
もし、データが100件あれば発見できたかどうか探すのが大変です。
もう少し工夫して、発見できた場合も発見できなかった場合もメッセージは1回だけ表示させるようにしてみてください。
ヒントは「発見したかどうかを判断する変数を新しく作る」でどうでしょう。
解答例です。
<sample program 065-03-2>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; int input; int found = 0; printf("探したいデータを入力してください:"); scanf("%d", &input); for (i = 0; i < COUNT; i++) { if (data[i] == input) { found = 1; } } if (found == 1) { printf("発見!\n"); } else { printf("発見できず・・・\n"); } return 0; } |
<実行結果1>
探したいデータを入力してください:98 発見! 続行するには何かキーを押してください・・・
<実行結果2>
探したいデータを入力してください:33 発見できず・・・ 続行するには何かキーを押してください・・・
発見できたかどうか判断するための変数foundを追加し初期値として0を入れておきました。
入力したデータと同じ値が発見された場合、変数foundの中身を1に変更し、引き続き調査を進めています。
すべての調査が終わった後に、変数foundの中身をチェックすれば発見できたかどうかが分ります。
このような変数の使い方をフラグといいます。
フラグについてはこちらでも説明しました。
次は、入力したデータが見つかった場合、見つかった場所(添え字)を表示するプログラムにしてみましょう。
<実行結果1>
探したいデータを入力してください:98 4番目の要素に入っています。 続行するには何かキーを押してください・・・
<実行結果2>
探したいデータを入力してください:33 発見できず・・・ 続行するには何かキーを押してください・・・
<実行結果3>
探したいデータを入力してください:12 2番目の要素に入っています。 8番目の要素に入っています。 続行するには何かキーを押してください・・・
解答例です。
<sample program 065-04>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; int input; int found = 0; printf("探したいデータを入力してください:"); scanf("%d", &input); for (i = 0; i < COUNT; i++) { if (data[i] == input) { found = 1; printf("%d番目の要素に入っています。\n", i); } } if (found == 0) { printf("発見できず・・・\n"); } return 0; } |
<実行結果1>
探したいデータを入力してください:98 4番目の要素に入っています。 続行するには何かキーを押してください・・・
<実行結果2>
探したいデータを入力してください:33 発見できず・・・ 続行するには何かキーを押してください・・・
<実行結果3>
探したいデータを入力してください:12 2番目の要素に入っています。 8番目の要素に入っています。 続行するには何かキーを押してください・・・
他にも色々な方法が考えられると思いますので、柔軟に考えてみてください。
では、最後に次のようなプログラムを作ってください。
配列dataの中には12のように複数存在する数があります。
上のプログラムでは、2カ所に存在する場合、それぞれの入っている要素の番号を表示しました。
しかし、単純に存在するかしないかだけを調査したい場合は、1つ目の12を発見した時点で、それ以上調査することは無意味になります。
そこで、探したいデータが見つかったら直ちに結果を表示し、終了するよう変更してみてください。
<実行結果1>
探したいデータを入力してください:98 発見! 続行するには何かキーを押してください・・・
<実行結果2>
探したいデータを入力してください:33 発見できず・・・ 続行するには何かキーを押してください・・・
<実行結果3>
探したいデータを入力してください:12 発見! 続行するには何かキーを押してください・・・
解答例です。
<sample program 065-05>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 12, 67, 98, 55, 32, 76, 12, 88 }; int i; int input; int found = 0; printf("探したいデータを入力してください:"); scanf("%d", &input); for (i = 0; i < COUNT; i++) { if (data[i] == input) { found = 1; break; } } if (found == 1) { printf("発見!\n"); } else { printf("発見できず・・・\n"); } return 0; } |
<実行結果1>
探したいデータを入力してください:98 発見! 続行するには何かキーを押してください・・・
<実行結果2>
探したいデータを入力してください:33 発見できず・・・ 続行するには何かキーを押してください・・・
<実行結果3>
探したいデータを入力してください:12 発見! 続行するには何かキーを押してください・・・
見つかった時点でbreakすれば良いですね。
今回は配列を使った基本的なアルゴリズム(問題解決法)の1つ「線形探索(シーケンシャルサーチ)」についての話でした。