★データ構造(配列5)★


今回は、配列の中身を調べるというテーマでプログラムを考えてみたいと思います。

すでに配列にデータが入っている状態を想定し、色々なプログラムを作ります。


では最初の問題です。

次のプログラムを見てください。


<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>を改良して作ってください。

<実行結果>

発見!
続行するには何かキーを押してください・・・









































解答例です。


<sample program 065-02>

#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つ「線形探索(シーケンシャルサーチ)」についての話でした。


次へ

戻る

目次へ