アフィリエイト広告を利用しています

広告

posted by fanblog

2017年11月23日

《その148》 汎用ユーティリティ関数 bsearch & p.111演習3-6


 bsearch関数

// bsearch関数(あらゆる型の配列からの探索を行うことができる。)
// #include <cstdlib>
// @ A B C
// ↓ ↓ ↓ ↓
// void* bsearch(const void* key,
// const void* base, size_t nmemb, sizt_t size,
// int (*compar)(const void*, const void*));
// ↑
// D 比較関数


・ bsearch関数は、キー値@と一致する配列要素へのポインタを返します。
  (一致する要素が見つからなければ、空ポインタを返します。)
Aは配列の先頭要素へのポインタです。
・ bsearch関数は、引数@,Avoid型として受け取ります。
  (void型ポインタは、どのようなポインタ型でも受け取る汎用ポインタ)
Bは配列要素の個数です。
Cは配列要素の大きさです。
比較関数D 例えば int_cmp を bsearch関数に渡す際には、キャストが必要です。
    reinterpret_cast<int(*)(const void*, const void*)>(int_cmp);
   比較関数は、配列要素の大小の判定方法を bsearch関数 に教えます
   比較関数は二つの引数を比較して、第1引数の値が小さければ負の値
   を、大きければ正の値を、二つが等しければ 0 を返す仕様
にします。
bsearch関数に渡す探索対象の配列は、ソート済みでなければなりません


 bsearch関数が返す配列要素へのポインタは void*型です。
そのため、次のプログラムでは、それを int*型にキャストしています(void型ポインタをint型にする際は、明示的な型キャストが必要です)。
このプログラムでは、x が int型配列の先頭要素へのポインタ、p がキー値と一致するint型配列要素へのポインタです。
二つのポインタ x, p は同じ int型配列の要素を指す int型ポインタですから、その差、
   p - x
は、p が指す配列要素の添字の値と一致します。

// ------------------------------------------
#include <cstdlib>
#include <iostream>
using namespace std;

int int_cmp(const int* a, const int* b) { // 比較関数
return *a < *b ? -1 : *a > *b ? 1: 0;
}

int main()
{
int x[] = { 15, 18, 18, 23, 39, 57, 68, 72 };
int nx = sizeof(x) / sizeof(x[0]); // 配列の要素数
for (int i = 0; i < nx; i++)
cout << "x[" << i << "]…" << x[i] << " ";
cout << '\n';


int no;
cout << "探索する値 : ";
cin >> no; // キー値が格納されたオブジェクト

int* p = reinterpret_cast<int*>(
bsearch(
&no, // @ キー値が格納されているオブジェクトへのポインタ
x, // A 配列の先頭要素へのポインタ
nx, // B 配列の要素数
sizeof(int), // C 配列要素の大きさ
// D 比較関数へのポインタ(bsearch関数が受け取れる型にキャスト)
reinterpret_cast<int(*)(const void*, const void*)>(int_cmp)
)
);

if (p != NULL)
cout << "x[" << p - x << "]が一致\n";
else
cout << "見つかりません。\n";
}
// ------------------------------------------

e03_00092.png

e03_00102.png



新版明解C++中級編 p.111 演習3-6
 bsearch関数を用いて、文字列の配列からの探索を行うプログラムを作成せよ。
 (@) 「2次元配列で実現された文字列の配列からの探索を行うプログラム」と、
 (A) 「文字列の先頭文字へのポインタの配列で実現された文字列からの探索を行うプログラム」の二つを作ること。

//  (@)
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;

int charstr_cmpr(const char* a, const char* b) {
return strcmp(a, b); // strcmp関数 … ヘッダ<cstring>
}

int main() {
const char s[][10] = { "abc", "abcd", "ac", "bca", "cab", "cba" };

for (int i = 0; i < sizeof(s) / sizeof(s[0]); i++)
cout << s[i] << " ";
cout << '\n';

while (1) {
char key[20];
cout << "◆探索文字列 : key = "; cin >> key;

char* p = reinterpret_cast<char*>(
bsearch(
key, s, sizeof(s) / sizeof(s[0]), sizeof(s[0]),
reinterpret_cast<int(*)(const void*, const void*)>(charstr_cmpr)
)
);
if (p != NULL)
cout << "s[" << (p - s[0]) / sizeof(s[0]) << "]が一致\n";
else
cout << "無し\n";
int cont;
cout << "継続(1) or 終了(0) : "; cin >> cont;
if (!cont) break;
else cout << '\n';
}
}

e03_1101.png


//  (A)
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;

int cmpr(const char* a, const char** b) {
return strcmp(a, *b); // strcmp関数 … ヘッダ<cstring>
}

int main() {
const char* s[] = { "abc", "abcd", "ac", "bca", "cab", "cba" };
for (int i = 0; i < sizeof(s) / sizeof(s[0]); i++)
cout << s[i] << " ";
cout << '\n';

while (1) {
char key[100];
cout << "キー値 : "; cin >> key;

char** p = reinterpret_cast<char**>(
bsearch(
key, s, sizeof(s) / sizeof(s[0]), sizeof(char*),
reinterpret_cast<int(*)(const void*, const void*)>(cmpr)
)
);

if (p != NULL)
cout << "s[" << p - s << "]が一致\n";
else
cout << "無し\n";
int cont;
cout << "継続(1) or 終了(0) : "; cin >> cont;
if (!cont) break;
else cout << '\n';
}
}

e03_1102.png


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/6999226
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。