★データ構造(配列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以下のデータだけ表示するプログラムを作ってください。
<実行結果 VC++ Express Edition>
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;
}
|
<実行結果 VC++ Express Edition>
23
45
12
32
12
続行するには何かキーを押してください・・・
以前にも書きましたが、人間は「ぱっ」と見ればどれが50以下か判断できます。
しかし、コンピュータは1つ1つ調べないと判断できません。
ループの中でif文を使い、1つ1つ50以下かどうかを調べて表示するのです。
では、次に行ってみましょう。
今度は、配列dataの中に55があるかどうか調べ、もしあれば「発見!」と表示します。
先ほどのプログラムと同じく<sample program 065-00>を改良して作ってください。
<実行結果 VC++ Express Edition>
発見!
続行するには何かキーを押してください・・・
解答例です。
<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;
}
|
<実行結果 VC++ Express Edition>
発見!
続行するには何かキーを押してください・・・
これも55があるかどうかは人間であれば瞬時に判断できますが、コンピュータは1つずつ調べなければなりません。
少し改良すればできますので、そう難しくはないですね。
次へ進みましょう。
キーボードからデータを入力し、入力した値が配列dataの中にあれば「発見!」と表示します。
無かったら「発見できず・・・」と表示します。
これも<sample program 065-00>を改良して作ってください。
<実行結果 VC++ Express Edition>
探したいデータを入力してください:98
発見!
続行するには何かキーを押してください・・・
解答例の前に・・・
例えば98と入力した場合、このようになっていませんか?
<実行結果 VC++ Express Edition>
探したいデータを入力してください: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;
}
|
<実行結果 VC++ Express Edition>
探したいデータを入力してください: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 VC++ Express Edition>
探したいデータを入力してください:98
発見!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
探したいデータを入力してください:33
発見できず・・・
続行するには何かキーを押してください・・・
発見できたかどうか判断するための変数foundを追加し初期値として0を入れておきました。
入力したデータと同じ値が発見された場合、変数foundの中身を1に変更し、引き続き調査を進めています。
すべての調査が終わった後に、変数foundの中身をチェックすれば発見できたかどうかが分ります。
このような変数の使い方をフラグといいます。
フラグについてはこちらでも説明しました。
次は、入力したデータが見つかった場合、見つかった場所(添え字)を表示するプログラムにしてみましょう。
<実行結果1 VC++ Express Edition>
探したいデータを入力してください:98
4番目の要素に入っています。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
探したいデータを入力してください:33
発見できず・・・
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
探したいデータを入力してください: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 VC++ Express Edition>
探したいデータを入力してください:98
4番目の要素に入っています。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
探したいデータを入力してください:33
発見できず・・・
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
探したいデータを入力してください:12
2番目の要素に入っています。
8番目の要素に入っています。
続行するには何かキーを押してください・・・
他にも色々な方法が考えられると思いますので、柔軟に考えてみてください。
では、最後に次のようなプログラムを作ってください。
配列dataの中には12のように複数存在する数があります。
上のプログラムでは、2カ所に存在する場合、それぞれの入っている要素の番号を表示しました。
しかし、単純に存在するかしないかだけを調査したい場合は、1つ目の12を発見した時点で、それ以上調査することは無意味になります。
そこで、探したいデータが見つかったら直ちに結果を表示し、終了するよう変更してみてください。
<実行結果1 VC++ Express Edition>
探したいデータを入力してください:98
発見!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
探したいデータを入力してください:33
発見できず・・・
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
探したいデータを入力してください: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 VC++ Express Edition>
探したいデータを入力してください:98
発見!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
探したいデータを入力してください:33
発見できず・・・
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
探したいデータを入力してください:12
発見!
続行するには何かキーを押してください・・・
見つかった時点でbreakすれば良いですね。
今回は配列を使った基本的なアルゴリズム(問題解決法)の1つ「線形探索(シーケンシャルサーチ)」についての話でした。