:: reverse dictionary ::
※ソースファイルについて
配列の要素をソートするには、qsort 関数を使います。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <search.h> #define STR_MAX 256 /* 文字列の最大長 */ /* 比較関数 */ int strcmp_asc(const void *, const void *); int strcmp_desc(const void *, const void *);
int main(void) { /* ソートするデータ */ char systems[][STR_MAX] = { "Windows" , "ウィンドウズ" , "Linux" , "リナックス" , "Solaris" , "ソラリス" }; int i; int length; /* 要素数を求める */ length = sizeof(systems) / STR_MAX; /* 昇順でソート */ qsort(systems, length, STR_MAX, strcmp_asc); printf("▼昇順\n"); for (i = 0; i < length; i++) { printf("systems[%d]=%s\n", i, systems[i]); } /* 降順でソート */ qsort(systems, length, STR_MAX, strcmp_desc); printf("▼降順\n"); for (i = 0; i < length; i++) { printf("systems[%d]=%s\n", i, systems[i]); } return EXIT_SUCCESS; } /** * 文字列を辞書式順序の昇順で比較します。 * @param sa 比較する文字列 * @param sb 比較する文字列 * @return sa が sb と等しい場合は 0 、 * sa が sb より小さい場合は -1 以下、 * sa が sb より大きい場合は 1 以上 */ int strcmp_asc(const void *sa, const void *sb) { return strcmp((char *)sa, (char *)sb); } /** * 文字列を辞書式順序の降順で比較します。 * @param sa 比較する文字列 * @param sb 比較する文字列 * @return sa が sb と等しい場合は 0 、 * sa が sb より小さい場合は 1 以上、 * sa が sb より大きい場合は -1 以下 */ int strcmp_desc(const void *sa, const void *sb) { return strcmp((char *)sb, (char *)sa); }
次のような出力になります。
▼昇順 systems[0]=Linux systems[1]=Solaris systems[2]=Windows systems[3]=ウィンドウズ systems[4]=ソラリス systems[5]=リナックス ▼降順 systems[0]=リナックス systems[1]=ソラリス systems[2]=ウィンドウズ systems[3]=Windows systems[4]=Solaris systems[5]=Linux
void qsort(void *a, size_t n, size_t sz, int (__cdecl *cf)(const void *ea, const void *eb))
配列 a の要素 n 個をソートします。
sz には、要素のサイズ(バイト数)を指定します。
ソートの際、比較関数 cf が呼び出されます。
cf には、独自に作成した比較関数を指定します。
比較関数は、2つの引数を取るように作成します。
引数の型は、void ポインタ( const void * )です。
ここでは説明のため、その引数を ea 、eb とします。 この ea と eb に比較する要素が渡されるので、それを比較した値を返すようにします。
昇順でソートする場合、返す値は次のようになります。
降順でソートする場合は、昇順の正と負を逆にします。
昇順と降順の比較関数を用意することで、両方のソートに対応できます。
a … ソートする配列
n … ソートする要素の個数
sz … 要素のサイズ(バイト数)
cf … 比較関数
ソートには、クイックソートのアルゴリズムが適用されます。
比較関数 cf の戻り値は、文字列比較関数の戻り値と同じです。
要素が文字列であれば、通常は文字列比較関数を cf から呼び出すだけで済みます。
文字列の配列だけでなく、他の型の配列もソートできます。
次の3つの例を挙げておきます。
#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <search.h> #define STR_MAX 256 /* 文字列の最大長 */ /* 比較関数 */ int wcscmp_asc(const void *, const void *); int wcscmp_desc(const void *, const void *);
int main(void) { /* ソートするデータ */ wchar_t systems[][STR_MAX] = { L"Windows" , L"ウィンドウズ" , L"Linux" , L"リナックス" , L"Solaris" , L"ソラリス" }; int i; int length; int datasize = sizeof(wchar_t) * STR_MAX; setlocale(LC_ALL, "ja"); /* ロケールを日本語に設定 */ /* 要素数を求める */ length = sizeof(systems) / datasize; /* 昇順でソート */ qsort(systems, length, datasize, wcscmp_asc); wprintf(L"▼昇順\n"); for (i = 0; i < length; i++) { wprintf(L"systems[%d]=%s\n", i, systems[i]); } /* 降順でソート */ qsort(systems, length, datasize, wcscmp_desc); wprintf(L"▼降順\n"); for (i = 0; i < length; i++) { wprintf(L"systems[%d]=%s\n", i, systems[i]); } return EXIT_SUCCESS; } /** * ワイド文字列を辞書式順序の昇順で比較します。 * @param sa 比較するワイド文字列 * @param sb 比較するワイド文字列 * @return sa が sb と等しい場合は 0 、 * sa が sb より小さい場合は -1 以下、 * sa が sb より大きい場合は 1 以上 */ int wcscmp_asc(const void *sa, const void *sb) { return wcscmp((wchar_t *)sa, (wchar_t *)sb); } /** * ワイド文字列を辞書式順序の降順で比較します。 * @param sa 比較するワイド文字列 * @param sb 比較するワイド文字列 * @return sa が sb と等しい場合は 0 、 * sa が sb より小さい場合は 1 以上、 * sa が sb より大きい場合は -1 以下 */ int wcscmp_desc(const void *sa, const void *sb) { return wcscmp((wchar_t *)sb, (wchar_t *)sa); }
次のような出力になります。
▼昇順 systems[0]=Linux systems[1]=Solaris systems[2]=Windows systems[3]=ウィンドウズ systems[4]=ソラリス systems[5]=リナックス ▼降順 systems[0]=リナックス systems[1]=ソラリス systems[2]=ウィンドウズ systems[3]=Windows systems[4]=Solaris systems[5]=Linux
#include <stdio.h> #include <stdlib.h> #include <search.h> /* 比較関数 */ int numcmp_asc(const void *, const void *); int numcmp_desc(const void *, const void *);
int main(void) { /* ソートするデータ */ int nums[] = {100, 2, 200, 1, 20, 10}; int i; int length; int datasize = sizeof(int); /* 要素数を求める */ length = sizeof(nums) / datasize; /* 昇順でソート */ qsort(nums, length, datasize, numcmp_asc); printf("▼昇順\n"); for (i = 0; i < length; i++) { printf("nums[%d]=%d\n", i, nums[i]); } /* 降順でソート */ qsort(nums, length, datasize, numcmp_desc); printf("▼降順\n"); for (i = 0; i < length; i++) { printf("nums[%d]=%d\n", i, nums[i]); } return EXIT_SUCCESS; } /** * 数値を昇順で比較します。 * @param na 比較する数値 * @param nb 比較する数値 * @return na が nb と等しい場合は 0 、 * na が nb より小さい場合は -1 以下、 * na が nb より大きい場合は 1 以上 */ int numcmp_asc(const void *na, const void *nb) { return *(int *)na - *(int *)nb; } /** * 数値を降順で比較します。 * @param na 比較する数値 * @param nb 比較する数値 * @return na が nb と等しい場合は 0 、 * na が nb より小さい場合は 1 以上、 * na が nb より大きい場合は -1 以下 */ int numcmp_desc(const void *na, const void *nb) { return *(int *)nb - *(int *)na; }
次のような出力になります。
▼昇順 nums[0]=1 nums[1]=2 nums[2]=10 nums[3]=20 nums[4]=100 nums[5]=200 ▼降順 nums[0]=200 nums[1]=100 nums[2]=20 nums[3]=10 nums[4]=2 nums[5]=1
#include <stdio.h> #include <stdlib.h> #include <search.h> #define STR_MAX 256 /* 文字列の最大長 */ /* 比較関数 */ int scorecmp_desc(const void *, const void *); /* プレイヤーの情報 */ typedef struct player { char name[STR_MAX]; /* 名前 */ long score; /* 得点 */ } Player;
int main(void) { /* ソートするデータ */ Player players[] = { {"田中", 32100} , {"鈴木", 78900} , {"山田", 45000} , {"佐藤", 60000} }; int i; int length; int datasize = sizeof(Player); /* 要素数を求める */ length = sizeof(players) / datasize; /* 得点の降順でソート */ qsort(players, length, datasize, scorecmp_desc); printf("▼得点の降順\n"); printf("[名前] [得点]\n"); for (i = 0; i < length; i++) { printf("%s %d\n", players[i].name, players[i].score); } return EXIT_SUCCESS; } /** * 得点の降順で比較します。 * @param pa 比較するプレイヤー * @param pb 比較するプレイヤー * @return pa の得点が pb の得点と等しい場合は 0 、 * pa の得点が pb の得点より小さい場合は 1 以上、 * pa の得点が pb の得点より大きい場合は -1 以下 */ int scorecmp_desc(const void *pa, const void *pb) { return ((Player *)pb)->score - ((Player *)pa)->score; }
次のような出力になります。
▼得点の降順 [名前] [得点] 鈴木 78900 佐藤 60000 山田 45000 田中 32100
Copyright (C) 2005-2007 Noto Watabe. All rights reserved.
e-mail:wmh@always-pg.com