unordered_multisetは要素の重複が許されることを除き、unordered_setと同じである。
ハッシュテーブルの実装において、ハッシュ値の衝突はチェイン法によって解決する。 チェイン法で使われるリンクリストをバケット と呼ぶこととする。 また、バケットの平均要素数(全要素数 / バケット数)をロードファクター と呼ぶ。 要素挿入後のロードファクターが、設定されているロードファクターの上限を超える場合、 自動的にバケットを拡張して再ハッシュが行われる。
unordered_set/unordered_multisetを使うには、<cstl/unordered_set.h>をインクルードし、以下のマクロを用いてコードを展開する必要がある。
#include <cstl/unordered_set.h> #define CSTL_UNORDERED_SET_INTERFACE(Name, Type) #define CSTL_UNORDERED_SET_IMPLEMENT(Name, Type, Haser, Compare) #define CSTL_UNORDERED_MULTISET_INTERFACE(Name, Type) #define CSTL_UNORDERED_MULTISET_IMPLEMENT(Name, Type, Haser, Compare)
CSTL_UNORDERED_SET_INTERFACE() は任意の名前と要素の型のunordered_setのインターフェイスを展開する。 CSTL_UNORDERED_SET_IMPLEMENT() はその実装を展開する。
CSTL_UNORDERED_MULTISET_INTERFACE() は任意の名前と要素の型のunordered_multisetのインターフェイスを展開する。 CSTL_UNORDERED_MULTISET_IMPLEMENT() はその実装を展開する。
#include <stdio.h> #include <cstl/unordered_set.h> /* unordered_setのインターフェイスと実装を展開 */ CSTL_UNORDERED_SET_INTERFACE(IntUSet, int) CSTL_UNORDERED_SET_IMPLEMENT(IntUSet, int, IntUSet_hash_int, CSTL_EQUAL_TO) int main(void) { int i; /* イテレータ */ IntUSetIterator pos; /* intのunordered_setを生成。 * 型名・関数のプレフィックスはIntUSetとなる。 */ IntUSet *uset = IntUSet_new(); /* 要素を挿入 */ for (i = 0; i < 64; i++) { IntUSet_insert(uset, i, NULL); } /* 要素数 */ printf("size: %d\n", IntUSet_size(uset)); for (pos = IntUSet_begin(uset); pos != IntUSet_end(uset); pos = IntUSet_next(pos)) { /* イテレータによる要素の読み出し(書き換えはできない) */ printf("%d, ", *IntUSet_data(pos)); } printf("\n"); /* 3以上の要素を削除 */ IntUSet_erase_range(uset, IntUSet_find(uset, 3), IntUSet_end(uset)); for (pos = IntUSet_begin(uset); pos != IntUSet_end(uset); pos = IntUSet_next(pos)) { /* イテレータによる要素の読み出し(書き換えはできない) */ printf("%d, ", *IntUSet_data(pos)); } printf("\n"); /* 使い終わったら破棄 */ IntUSet_delete(uset); return 0; }
コンパイラオプションによって、NDEBUGマクロが未定義かつCSTL_DEBUGマクロが定義されているならば、 assertマクロが有効になり、関数の事前条件に違反するとプログラムの実行を停止する。
#define CSTL_UNORDERED_SET_INTERFACE | ( | Name, | |||
Type | ) |
unordered_set用インターフェイスマクロ
任意の名前と要素の型のunordered_setのインターフェイスを展開する。
Name | 既存の型と重複しない任意の名前。unordered_setの型名と関数のプレフィックスになる | |
Type | 任意の要素の型 |
Type を括弧で括らないこと。
#define CSTL_UNORDERED_SET_IMPLEMENT | ( | Name, | |||
Type, | |||||
Hasher, | |||||
Compare | ) |
unordered_set用実装マクロ
CSTL_UNORDERED_SET_INTERFACE()で展開したインターフェイスの実装を展開する。
Name | 既存の型と重複しない任意の名前。unordered_setの型名と関数のプレフィックスになる | |
Type | 任意の要素の型 | |
Hasher | ハッシュ関数 | |
Compare | 要素を比較する関数またはマクロ |
int comp(Type x, Type y);
size_t hash(Type x);
Type を括弧で括らないこと。
#define CSTL_UNORDERED_MULTISET_INTERFACE | ( | Name, | |||
Type | ) |
unordered_multiset用インターフェイスマクロ
任意の名前と要素の型のunordered_multisetのインターフェイスを展開する。
使用方法は CSTL_UNORDERED_SET_INTERFACE()と同じである。
#define CSTL_UNORDERED_MULTISET_IMPLEMENT | ( | Name, | |||
Type, | |||||
Hasher, | |||||
Compare | ) |
unordered_multiset用実装マクロ
CSTL_UNORDERED_MULTISET_INTERFACE()で展開したインターフェイスの実装を展開する。
使用方法は CSTL_UNORDERED_SET_IMPLEMENT()と同じである。
#define CSTL_EQUAL_TO | ( | x, | |||
y | ) | ((x) == (y) ? 0 : 1) |
整数比較
要素の値に整数型を指定した場合、 CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_INTERFACE() の Compare 引数に指定する。
x | 1つ目の値 | |
y | 2つ目の値 |
0 | x == y の場合 | |
非0 | x != y の場合 |
typedef struct UnorderedSet UnorderedSet |
unordered_set/unordered_multisetの型
抽象データ型となっており、内部データメンバは非公開である。
以下、 UnorderedSet_new*() から返されたUnorderedSet構造体へのポインタをunordered_setオブジェクトという。
typedef PRIVATE_TYPE* UnorderedSetIterator |
イテレータ
要素の位置を示す。 イテレータ同士の比較は、 == , != が使用できる。< , > , <= , >= は使用できない。
以下、関数から返されたイテレータを有効なイテレータという。 未初期化のイテレータ、または削除された要素のイテレータ、または値が0のイテレータを無効なイテレータという。
PRIVATE_TYPEは非公開の型である。
typedef PRIVATE_TYPE* UnorderedSetLocalIterator |
ローカルイテレータ
一つのバケットの中の要素を巡回するためのイテレータ。 複数のバケットにまたがって巡回することはできない。
PRIVATE_TYPEは非公開の型である。
UnorderedSet* UnorderedSet_new | ( | void | ) |
生成
要素数が0のunordered_set/unordered_multisetを生成する。
メモリ不足の場合、NULLを返す。
UnorderedSet* UnorderedSet_new_rehash | ( | size_t | n | ) |
バケット数を指定して生成
少なくとも n 個のバケットを確保し、 要素数が0のunordered_set/unordered_multisetを生成する。
n | バケット数 |
メモリ不足の場合、NULLを返す。
void UnorderedSet_delete | ( | UnorderedSet * | self | ) |
破棄
self のすべての要素を削除し、self を破棄する。 self がNULLの場合、何もしない。
self | unordered_setオブジェクト |
size_t UnorderedSet_size | ( | UnorderedSet * | self | ) |
要素数を取得
self | unordered_setオブジェクト |
int UnorderedSet_empty | ( | UnorderedSet * | self | ) |
空チェック
self | unordered_setオブジェクト |
self の要素数が1以上の場合、0を返す。
UnorderedSetIterator UnorderedSet_begin | ( | UnorderedSet * | self | ) |
最初の要素のイテレータ
self | unordered_setオブジェクト |
UnorderedSetIterator UnorderedSet_end | ( | UnorderedSet * | self | ) |
最後の要素の次のイテレータ
self | unordered_setオブジェクト |
UnorderedSetIterator UnorderedSet_next | ( | UnorderedSetIterator | pos | ) |
次のイテレータ
pos | イテレータ |
pos が UnorderedSet_end() でないこと。
T const* UnorderedSet_data | ( | UnorderedSetIterator | pos | ) |
イテレータによる要素のアクセス
pos | イテレータ。pos の型は UnorderedSetLocalIterator でもよい。 |
pos が UnorderedSet_end() または UnorderedSet_bucket_end() でないこと。
UnorderedSetIterator UnorderedSet_insert | ( | UnorderedSet * | self, | |
T | data, | |||
int * | success | |||
) |
要素を挿入(unordered_set専用)
data のコピーをself に挿入する。
self | unordered_setオブジェクト | |
data | 挿入するデータ | |
success | 成否を格納する変数へのポインタ。ただし、NULLを指定した場合はアクセスしない。 |
self が既にdata という値の要素を持っている場合、挿入を行わず、*success に0を格納し、その要素のイテレータを返す。
メモリ不足の場合、*success に0を格納し、self の変更を行わず0を返す。
UnorderedSetIterator UnorderedSet_insert | ( | UnorderedSet * | self, | |
T | data | |||
) |
要素を挿入(unordered_multiset専用)
data のコピーをself に挿入する。 self が既にdata という値の要素を持っている場合、その要素と同じバケットに挿入される。
self | unordered_setオブジェクト | |
data | 挿入するデータ |
メモリ不足の場合、self の変更を行わず0を返す。
int UnorderedSet_insert_range | ( | UnorderedSet * | self, | |
UnorderedSetIterator | first, | |||
UnorderedSetIterator | last | |||
) |
指定範囲の要素を挿入
[first, last)の範囲の要素のコピーをself に挿入する。 unordered_multisetの場合、[first, last)の要素はself が持つ要素でもよい。
self | unordered_setオブジェクト | |
first | コピー元の範囲の開始位置 | |
last | コピー元の範囲の終了位置 |
メモリ不足の場合、self の変更を行わず0を返す。
UnorderedSetIterator UnorderedSet_erase | ( | UnorderedSet * | self, | |
UnorderedSetIterator | pos | |||
) |
要素を削除
self のpos が示す位置の要素を削除する。
self | unordered_setオブジェクト | |
pos | 削除する要素の位置 |
pos が UnorderedSet_end() でないこと。
UnorderedSetIterator UnorderedSet_erase_range | ( | UnorderedSet * | self, | |
UnorderedSetIterator | first, | |||
UnorderedSetIterator | last | |||
) |
指定範囲の要素を削除
self の[first, last)の範囲の要素を削除する。
self | unordered_setオブジェクト | |
first | 削除する範囲の開始位置 | |
last | 削除する範囲の終了位置 |
size_t UnorderedSet_erase_key | ( | UnorderedSet * | self, | |
T | data | |||
) |
指定した値の要素を削除
self のdata という値の要素をすべて削除する。
self | unordered_setオブジェクト | |
data | 削除する要素の値 |
void UnorderedSet_clear | ( | UnorderedSet * | self | ) |
全要素を削除
self のすべての要素を削除する。
self | unordered_setオブジェクト |
void UnorderedSet_swap | ( | UnorderedSet * | self, | |
UnorderedSet * | x | |||
) |
交換
self とx の内容を交換する。
self | unordered_setオブジェクト | |
x | self と内容を交換するunordered_setオブジェクト |
size_t UnorderedSet_count | ( | UnorderedSet * | self, | |
T | data | |||
) |
指定した値の要素をカウント
self | unordered_setオブジェクト | |
data | カウントする要素の値 |
UnorderedSetIterator UnorderedSet_find | ( | UnorderedSet * | self, | |
T | data | |||
) |
指定した値の要素を検索
self のdata という値の最初の要素を検索する。
self | unordered_setオブジェクト | |
data | 検索する要素の値 |
見つからない場合、 UnorderedSet_end(self) を返す。
void UnorderedSet_equal_range | ( | UnorderedSet * | self, | |
T | data, | |||
UnorderedSetIterator * | first, | |||
UnorderedSetIterator * | last | |||
) |
指定した値の要素の範囲を取得
self | unordered_setオブジェクト | |
data | 検索する要素の値 | |
first | data という値の最初の要素のイテレータを格納する変数へのポインタ | |
last | data という値の最後の要素の次のイテレータを格納する変数へのポインタ |
last がNULLでないこと。
size_t UnorderedSet_bucket_count | ( | UnorderedSet * | self | ) |
バケット数を取得
self | unordered_setオブジェクト |
size_t UnorderedSet_bucket_size | ( | UnorderedSet * | self, | |
size_t | idx | |||
) |
一つのバケットの中の要素数を取得
self | unordered_setオブジェクト | |
idx | バケットのインデックス |
size_t UnorderedSet_bucket | ( | UnorderedSet * | self, | |
T | data | |||
) |
バケットのインデックスを取得
self | unordered_setオブジェクト | |
data | 要素の値 |
UnorderedSetLocalIterator UnorderedSet_bucket_begin | ( | UnorderedSet * | self, | |
size_t | idx | |||
) |
一つのバケットの中の最初の要素のローカルイテレータ
self | unordered_setオブジェクト | |
idx | バケットのインデックス |
UnorderedSetLocalIterator UnorderedSet_bucket_end | ( | UnorderedSet * | self, | |
size_t | idx | |||
) |
一つのバケットの中の最後の要素の次のローカルイテレータ
self | unordered_setオブジェクト | |
idx | バケットのインデックス |
UnorderedSetLocalIterator UnorderedSet_bucket_next | ( | UnorderedSetLocalIterator | pos | ) |
次のローカルイテレータ
pos | ローカルイテレータ |
pos が UnorderedSet_end() または UnorderedSet_bucket_end() でないこと。
float UnorderedSet_load_factor | ( | UnorderedSet * | self | ) |
ロードファクターを取得
バケットの平均要素数(全要素数 / バケット数)をロードファクターと呼ぶ。
self | unordered_setオブジェクト |
float UnorderedSet_get_max_load_factor | ( | UnorderedSet * | self | ) |
ロードファクターの上限を取得
self | unordered_setオブジェクト |
void UnorderedSet_set_max_load_factor | ( | UnorderedSet * | self, | |
float | z | |||
) |
ロードファクターの上限を設定
self | unordered_setオブジェクト | |
z | 設定するロードファクターの上限 |
int UnorderedSet_rehash | ( | UnorderedSet * | self, | |
size_t | n | |||
) |
バケットを拡張して再ハッシュ
バケット数を 少なくとも n 個に拡張し、全要素をハッシュ関数によって再び振り分ける。
self | unordered_setオブジェクト | |
n | バケット数 |
n がself の現在のバケット数以下の場合、self の変更を行わず非0を返す。
メモリ不足の場合、self の変更を行わず0を返す。
size_t UnorderedSet_hash_string | ( | const char * | data | ) |
文字列用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に const char * を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_wstring | ( | const wchar_t * | data | ) |
ワイド文字列用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に const wchar_t * を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_char | ( | char | data | ) |
char用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に char を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_schar | ( | signed char | data | ) |
signed char用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に signed char を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_uchar | ( | unsigned char | data | ) |
unsigned char用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に unsigned char を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_short | ( | short | data | ) |
short用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に short を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_ushort | ( | unsigned short | data | ) |
unsigned short用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に unsigned short を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_int | ( | int | data | ) |
int用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に int を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_uint | ( | unsigned int | data | ) |
unsigned int用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に unsigned int を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_long | ( | long | data | ) |
long用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に long を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |
size_t UnorderedSet_hash_ulong | ( | unsigned long | data | ) |
unsigned long用ハッシュ関数
CSTL_UNORDERED_SET_IMPLEMENT() , CSTL_UNORDERED_MULTISET_IMPLEMENT() の引数Type に unsigned long を指定した場合、 引数Hasher にこの関数を指定する。
data | 要素の値 |