今回は、配列の中身を調べるというテーマでプログラムを考えてみたいと思います。
すでに配列にデータが入っている状態を想定し、色々なプログラムを作ります。
では最初の問題です。
次のプログラムを見てください。
<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つ「線形探索(シーケンシャルサーチ)」についての話でした。