では、前回と違った方法で最大値を求める方法を考えます。
配列のデータは前回と同じものを使います。
この状態から以下の方法で最大値を求めます。
1.左端から隣り合った2つの要素を比較する。 2.左側(添え字の小さい方)が大きい場合、中身を入れ換える。 左側が小さい場合は何もしない。 3.これを左端から順に繰り返す。 |
言葉で書いても伝わらないので、図で表します。
まずは、左端から始めます。
data[0]とdata[1]の中身を比較します。
左側(data[0])が小さいため、何もしません。
次に、1つ右へ移ってdata[1]とdata[2]を比較します。
左側(data[1])の方が大きいため、data[1]とdata[2]を入れ換えます。
次に、1つ右へ移ってdata[2]とdata[3]を比較します。
左側(data[2])が小さいため、何もしません。
次に、1つ右へ移ってdata[3]とdata[4]を比較します。
左側(data[3])が小さいため、何もしません。
次に、1つ右へ移ってdata[4]とdata[5]を比較します。
左側(data[4])の方が大きいため、data[4]とdata[5]を入れ換えます。
次に、1つ右へ移ってdata[5]とdata[6]を比較します。
左側(data[5])の方が大きいため、data[5]とdata[6]を入れ換えます。
次に、1つ右へ移ってdata[6]とdata[7]を比較します。
左側(data[6])の方が大きいため、data[6]とdata[7]を入れ換えます。
次に、1つ右へ移ってdata[7]とdata[8]を比較します。
左側(data[7])の方が大きいため、data[7]とdata[8]を入れ換えます。
次に、1つ右へ移ってdata[8]とdata[9]を比較します。
左側(data[8])の方が大きいため、data[8]とdata[9]を入れ換えます。
これで、data[9]に最大値が入ります。
前回の方法「最大値を変数maxに入れておく」とは違って、配列の中身を入れ換えて、大きな数値を右へ右へと移動していく方法です。
連続して見るとこのようなイメージです。
さて、これをプログラムで実現したいと思います。
気をつけたい部分は、
1.配列の要素の入れ換え 2.隣の要素との比較 3.比較回数(ループ回数)
でしょうか。
1.配列の要素の入れ換え
覚えていますか?変数同士の入れ換えと同じです。
2.隣の要素との比較
隣の要素は、基準となる添え字+1で表現できます。
3.比較回数(ループ回数)
要素が10個あるから10回と思わないでくださいね。
※上の図を良く見てください。
<sample program 067-00>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 9, 67, 98, 55, 32, 76, 12, 88 }; int i; /* ここにプログラムを追加 */ printf("最大値は%dです。\n", data[9]); return 0; } |
<実行結果>
最大値は98です。 続行するには何かキーを押してください・・・
これをベースにいろいろと考えながら作成してみてください。
不足しているものは皆さんで考えて追加してください。
解答例です。
<sample program 067-01>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 9, 67, 98, 55, 32, 76, 12, 88 }; int i; int work; for (i = 0; i < COUNT - 1; i++) { if (data[i] > data[i + 1]) { work = data[i]; data[i] = data[i + 1]; data[i + 1] = work; } } printf("最大値は%dです。\n", data[9]); return 0; } |
<実行結果>
最大値は98です。 続行するには何かキーを押してください・・・
まず、配列の要素の入れ換えを行うには、変数が1つ不足しているため、変数workを追加しました。
最初は、
data[0]とdata[1]
を比較、次は
data[1]とdata[2]
を比較・・・と続けるため、
data[i]とdata[i + 1]
と書き、ループの中で比較しています。
変数iが0、1、2と変化していくにつれ、i+1は1、2、3と変化しますので、常に隣を指す添え字となります。
また、ループ回数は「COUNT−1」としています。
比較回数は図の通り、9回ですね。
条件を「COUNT」のみにしてしまうと、iは0から9まで変化することになります。
iが9になると、i+1は10になりますので、配列の範囲を超えてしまいます。
前回のプログラムでも最大値は求めることができますが、今回の方法との最大の違いは、実行前と実行後の配列の内容が変化するかしないかです。
前回の方法であれば、実行前と実行後の配列の中身(順番)は変化がありません。
今回の方法では、実行前と実行後で配列の中身(順番)が変わっています。
次のプログラムを実行して比べてみてください。
<sample program 067-02>
#include <stdio.h> #define COUNT 10 int main(void) { int data[COUNT] = { 23, 45, 9, 67, 98, 55, 32, 76, 12, 88 }; int i; int work; printf("実行前:"); for (i = 0; i < COUNT; i++) { printf("%3d", data[i]); } printf("\n"); for (i = 0; i < COUNT - 1; i++) { if (data[i] > data[i + 1]) { work = data[i]; data[i] = data[i + 1]; data[i + 1] = work; } } printf("最大値は%dです。\n", data[9]); printf("実行後:"); for (i = 0; i < COUNT; i++) { printf("%3d", data[i]); } printf("\n"); return 0; } |
<実行結果>
実行前: 23 45 9 67 98 55 32 76 12 88 最大値は98です。 実行後: 23 9 45 67 55 32 76 12 88 98 続行するには何かキーを押してください・・・
実行前と実行後に配列の要素(順番)が変化してはならない場合、この方法は使えません。
もし、使うとすれば配列をコピーしてから使う必要があります。
これを考えると前回のプログラムの方が優れているように見えますが、今回のプログラムは次への布石なのです。
次回は、この「入れ換える」という方法を応用して別のプログラムを組みます。