手作業をプログラミングする
では、こうして考えてみた並べ替えの手順をプログラムにしてみましょう。リスト1のようになります。
2つのループ
先に紹介したカードの並べ替え手順では、比較元のカードが1巡目、2巡目……と、1枚ずつ左へ移動していきました。その処理が外側の(カウンタ変数にiを使った)forループです。
そのループの中で、比較先を1枚ずつずらしていく処理が、内側(カウンタ変数にjを使った)forループになります。
関数swapは、比較元より比較先の方が小さかったときに、双方の値を入れ替えるための関数です。実際に引数の値を入れ替えるため、いわゆる「参照渡し」として引数には2つの値のアドレスを採ります。
元の数値の並び(カードの群れ)は配列になっているので、main関数の中からswap関数を呼び出すときには、配列の要素のアドレスを渡すことになります。
swap(&(card[i]), &(card[j]));
リスト1:
カードの並べ替え手順をプログラムにしたCのソース~ex5101.c
#include <stdio.h>
/* 元の配列(6個) */
int card[] = {6, 3, 2, 7, 1, 4};
/* 値の入れ替え */
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
/* main */
int main(void)
{
int i, j;
/* 元の状態を表示 */
printf("before...¥n");
for (i=0; i<=5; i++) {
printf("%d ", card[i]);
}
/* 外側のループ -- 比較元を1つずつずらしていく */
for (i=0; i<=5; i++) {
/* 内側のループ --
値を順次比較して比較元より比較先が
小さければ値を入れ替える */
for (j=i+1; j<=5; j++) {
if (card[i] > card[j]) {
swap(&(card[i]), &(card[j]));
}
}
}
/* 並べ替え後の状態を表示 */
printf("¥n");
printf("after...¥n");
for (i=0; i<=5; i++) {
printf("%d ", card[i]);
}
}
異なる値で検証する
これで、一応カードの並べ替え処理をプログラムにできました。しかし、他の数値では試していません。他の数値の組み合わせでも、同じように正しく並べ替えられているか調べることで、そのプログラムの汎用性が検証できます。
そこで、先のプログラムを、リスト2のようにユーザーが6個の数値を自由に(int型の範囲内ですが)入力できるように書き換えてみました。起動後のプロンプトに対して、6個の数値を半角のスペース区切りで入力する仕様jになっています。
実際に動作を試してみれば、どのような数値を入力しても、正しく昇順(小→大)に並べ替えられることが分かります。
リスト2:
ユーザーが値を自由に入力できるようにした並べ替えプログラムのソース~ex5102.c
#include <stdio.h>
/* 元の配列(6個) */
int card[6];
/* 値の入れ替え */
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
/* main */
int main(void)
{
int i, j;
/* ユーザーが値を入力 */
printf("input 6 numbers...¥n");
for (i=0; i<=5; i++) {
scanf("%d", &(card[i]));
}
/* 元の状態を表示 */
printf("before...¥n");
for (i=0; i<=5; i++) {
printf("%d ", card[i]);
}
/* 外側のループ -- 比較元を1つずつずらしていく */
for (i=0; i<=5; i++) {
/* 内側のループ --
値を順次比較して比較元より比較先が
小さければ値を入れ替える */
for (j=i+1; j<=5; j++) {
if (card[i] > card[j]) {
swap(&(card[i]), &(card[j]));
}
}
}
/* 並べ替え後の状態を表示 */
printf("¥n");
printf("after...¥n");
for (i=0; i<=5; i++) {
printf("%d ", card[i]);
}
}
|
|
|