プログラミング演習2(課題3:整列:第2回)

講義資料 講義資料(印刷用)

練習問題(1):配列の要素内の最大値を探すプログラム

ソリューション名 (example2_1)、ソースファイル名 (example2_1.c)

#include <stdio.h>
/* 2つの値(a,b)の大きい方を返すマクロ */
#define MAX(a,b) (((a)>(b))?(a):(b))

/**
 * 配列の要素内で最大値を探す関数
 * @param a 探索対象配列
 * @param n 配列の要素数
 * @return 最大値 
 */
int
find_max_value(const int a[], int n)
{
/* ここを実装せよ */
}

int
main(void) 
{
    int n = 10;
    int a[10] = {23,45,8,21,75,43,98,43,2,86};

    printf("%d\n", find_max_value(a, n));
    return 0;
}

出力例

98

練習問題(2):大文字と小文字を入れ替える

ソリューション名 (example2_2)、ソースファイル名 (example2_2.c)

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/**
 * 大文字だったら小文字に、小文字だったら大文字に変換、アルファベットでなければそのまま
 * @param c 検査対象文字
 * @return 変換後の文字 
 */
int
ul_exchange(int c) 
{
/* ここを実装せよ */
}

int
main(void) 
{
    char str[]="7-1-2 yOto, UsTunOmIYa";
    size_t i,len;

    len = strlen(str);

    printf("%s\n", str);
    for (i = 0; i < len; i++) {
    	str[i] = ul_exchange(str[i]);
    }
    printf("%s\n", str);
    return 0;
}

出力例

7-1-2 yOto, UsTunOmIYa
7-1-2 YoTO, uStUNoMiyA

練習問題(3):選択ソート

ソリューション名 (example2_3)、ソースファイル名 (example2_3.c)

#include <stdio.h> /* printf()利用のため */
#include <stdlib.h> /* rand()利用のため */
#include <time.h> /* clock()利用のため */
#define N 10 /* 整列対象要素数 */

/**
 * 配列の中身を表示する関数
 * @param a 表示する配列
 * @param n 配列の要素数
 */
void
print_array(const int a[], int n) 
{
    int i;

    for (i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

/**
 * 整列されているかどうか確認する関数 
 * @param a 確認対象配列
 * @param n 配列の要素数
 */
void
is_sorted(const int a[], int n)
{
    int i;

    for (i = 0;i < n - 1; i++) {
        if (a[i] > a[i + 1]) {
	        printf("昇順に整列されていません\n");
		    return;
		}
    }
    printf("昇順に整列されています\n");
}

/**
 * 選択ソート
 * @param a 整列対象配列
 * @param n 配列の要素数 
 */
void
selection_sort(int a[], int n) 
{
/* ここを実装せよ */
/* どうしてもわからない場合のヒント */
'http://www.ced.is.utsunomiya-u.ac.jp/lecture/2014/prog/p1/kadai3/hint2_3_1.html'
}

int 
main(void) 
{
    int i;
    int n = N;
    int a[N]; 
    clock_t start,end;

    /* 0からRAND_MAXの一様乱数をn個生成し、配列aに格納 */
    for (i = 0; i < n; i++) {
        a[i] = rand();
	/* 出力確認(print_array)するときは a[i]=rand()%100 としておくと見やすい */
    }
    /* 昇順にソートされているか確認(デバッグ用) */
    is_sorted(a, n);
    /* 配列の中身を確認(デバッグ用) */
    print_array(a, n);
    /* 開始時刻の取得 */
    start = clock();	
    /* 選択ソート関数の呼び出し */
    selection_sort(a, n); 	
    /* 終了時刻の取得 */
    end = clock(); 
    /* 配列の中身を確認(デバッグ用) */
    print_array(a, n);
    /* 昇順にソートされているか確認(デバッグ用) */
    is_sorted(a, n); 
    /* 実行時間の表示 */
    printf("%d 個の要素の選択ソートの実行に %f [秒]かかりました\n", n, (double)(end - start) / CLOCKS_PER_SEC); 
    return 0;
}
追加課題) 要素数(N)を100, 1000, 10000, 100000とした場合の実行時間を比較せよ
追加課題) 関数selection_sort中で配列の要素の比較、交換の回数をそれぞれ出力できるように改造せよ

出力例

昇順に整列されていません
昇順に整列されています
比較を 49995000 回、交換を 9999 回行いました
10000 個の要素の選択ソートの実行に 0.296000 [秒]かかりました

練習問題(4):挿入ソート

ソリューション名 (example2_4)、ソースファイル名 (example2_4.c)

#include <stdio.h> /* printf()利用のため */
#include <stdlib.h> /* rand()利用のため */
#include <time.h> /* clock()利用のため */
#define N 10 /* 整列対象要素数 */

/**
 * 配列の中身を表示する関数
 * @param a 表示する配列
 * @param n 配列の要素数
 */
void
print_array(const int a[], int n) 
{
    int i;

    for (i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

/**
 * 整列されているかどうか確認する関数 
 * @param a 確認対象配列
 * @param n 配列の要素数
 */
void
is_sorted(const int a[], int n) 
{
    int i;
    for (i = 0; i < n - 1; i++) {
        if (a[i] > a[i + 1]) {
	        printf("昇順に整列されていません\n");
    	    return;
		}
    }
    printf("昇順に整列されています\n");
}

/**
 * 挿入ソート
 * @param a 整列対象配列
 * @param n 配列の要素数 
 */
void
insertion_sort(int a[], int n) 
{
/* ここ実装せよ */
/* どうしてもわからない場合のヒント */
'http://www.ced.is.utsunomiya-u.ac.jp/lecture/2014/prog/p1/kadai3/hint2_4_1.html'
}

int 
main(void)
{
    int i;
    int n = N; /* 整列対象要素数 */
    int a[N]; 
    clock_t start,end;

    /* 0からRAND_MAXの一様乱数をn個生成し、配列aに格納 */
    for (i = 0; i < n; i++) {
        a[i] = rand();
	    /* 出力確認(print_array)するときは a[i]=rand()%100 としておくと見やすい */
    }
    /* 昇順にソートされているか確認(デバッグ用) */
    is_sorted(a, n); 
    /* 配列の中身を確認(デバッグ用) */
    print_array(a, n);
    /* 開始時刻の取得 */
    start = clock();
    /* 挿入ソート関数の呼び出し */
    insertion_sort(a, n); 
    /* 終了時刻の取得 */
    end = clock(); 
    /* 配列の中身を確認(デバッグ用) */
    print_array(a, n); 
    /* 昇順にソートされているか確認(デバッグ用) */
    is_sorted(a, n); 
    /* 実行時間の表示 */
    printf("%d 個の要素の挿入ソートの実行に %f [秒]かかりました\n", n, (double)(end - start) / CLOCKS_PER_SEC); 
    return 0;
}
追加課題) 要素数(N)を100, 1000, 10000, 100000とした場合の実行時間を比較せよ
追加課題) 関数insert_sort中で配列の要素の比較、交換の回数をそれぞれ出力できるように改造せよ

出力例

昇順に整列されていません
昇順に整列されています
比較を 24962883 回、交換を 24952888 回行いました
10000 個の要素の挿入ソートの実行に 0.405000 [秒]かかりました