C & C++ FAQ
|
|
標準ライブラリbsearch関数は、以下の形式をもっています。
#include <stdlib.h>
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
各引数に何を渡すかを、少しわかりやすくまとめるとると、以下のようになります。
- key
- 探索するキー値を指すポインタ。
- base
- 探索する配列の先頭要素へのポインタ。
- nmemb
- 探索する配列の要素数。
- size
- 探索する配列の要素の大きさ(バイト数)。int型の配列からを探索するのであればsizeof(int)。
- compar
- いわゆる“比較関数”へのポインタです。比較関数は、プログラム側で用意します。この関数は、以下のように定義します。
- 比較の対象となる二つの要素へのポインタを受け取る(以下、それらをxおよびyとする)。
- int型の値を返す。
- xの指す要素が、yの指す要素より、小さい(先頭側に位置する)のであれば、負の値を返す(値は何でもよい)。
- xの指す要素が、yの指す要素と同じであれば、0を返す。
- xの指す要素が、yの指す要素より、大きい(末尾側に位置する)のであれば、正の値を返す(値は何でもよい)。
bsearch関数を用いて、int型の配列を昇順にソートするプログラム例を以下に示します。
7個の整数を降順に入力してください。
x[0]:10
x[1]:23
x[2]:43
x[3]:45
x[4]:47
x[5]:60
x[6]:78
探索する値を入力してください:45
45は4番目にあります。 |
/*
bsearch関数を利用して要素を探索
*/
#include <stdio.h>
#include <stdlib.h>
/*--- 整数を比較する関数(降順用) ---*/
int int_cmpr(const int *a, const int *b)
{
if (*a < *b)
return (1);
else if (*a > *b)
return (-1);
else
return (0);
}
int main(void)
{
int i, ky, *p;
int x[7];
int nx = sizeof(x) / sizeof(x[0]);
printf("%d個の整数を降順に入力してください。\n", nx);
printf("x[0]:");
scanf("%d", &x[0]);
for (i = 1; i < nx; i++) {
do {
printf("x[%d]:", i);
scanf("%d", &x[i]);
} while (x[i] > x[i - 1]); /* 一つ前の値よりも多きければ再入力 */
}
printf("探索する値を入力してください:");
scanf("%d", &ky);
p = bsearch(&ky, /* 探索値へのポインタ */
x, /* 配列 */
nx, /* 要素数 */
sizeof(int), /* 要素の大きさ */
(int (*)(const void *, const void *))int_cmpr /* 比較関数 */
);
if (p == NULL)
puts("探索に失敗しました。");
else
printf("%dは%d番目にあります。\n", ky, (int)(p - &x[0]) + 1);
return (0);
}
もしも、配列が値の降順で並んでいるのであればreturn (*y - *x)と変更しましょう。
次に、構造体をソートする例を以下に示します。ここでは、名前の昇順、身長の昇順、体重の降順の例を示しています。
名前による探索を行います。
名前:Shibata・
x[1] : Shibata 170cm 52kg
もう一度探索しますか? (1)はい/(0)いいえ:0・/PRE> |
/*
bsearch関数を利用して構造体の配列からの探索
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10]; /* 名前 */
int height; /* 身長 */
int weight; /* 体重 */
} Person;
/*--- Person型の比較関数(名前昇順) ---*/
int npcmp(const Person *x, const Person *y)
{
return (strcmp(x->name, y->name));
}
int main(void)
{
Person x[]= {{"Nangoh", 172, 63}, /* 配列の要素は名前の昇順で */
{"Shibata", 170, 52}, /* 並んでいなければならない */
{"Sugiyama", 165, 50},
{"Takaoka", 180, 70},
{"Tsuji", 172, 80},
};
int nx = sizeof(x) / sizeof(x[0]); /* 配列xの要素数 */
int retry;
puts("名前による探索を行います。");
do {
Person temp, *p;
printf("名前:");
scanf("%s", temp.name);
p = bsearch(&temp, x, nx, sizeof(Person),
(int (*)(const void *, const void *))npcmp);
if (p == NULL)
puts("探索に失敗しました。");
else
printf("x[%d] : %s %dcm %dkg\n",
(int)(p - x), p->name, p->height, p->weight);
printf("もう一度探索しますか? (1)はい/(0)いいえ:");
scanf("%d", &retry);
} while (retry == 1);
return (0);
}
■ 根拠 ■
標準C
| §7.10.5.1
| The bsearch function
|
標準C99
| §7.20.5.1
| The bsearch function
|
標準C++
| §25.4
| C library algorithms
|
■ 参照 ■