This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
programming:cpp:container [2022/05/05 11:30] odagawa |
programming:cpp:container [2022/05/06 17:25] (current) odagawa |
||
---|---|---|---|
Line 16: | Line 16: | ||
<code cpp> | <code cpp> | ||
+ | #include < | ||
#include < | #include < | ||
Line 171: | Line 172: | ||
C++ の reference は[[https:// | C++ の reference は[[https:// | ||
map において一つのキーに対して複数の要素を許すようにしたもの. | map において一つのキーに対して複数の要素を許すようにしたもの. | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include <map> | ||
+ | |||
+ | int main (int argv, char *argv[]) { | ||
+ | |||
+ | std:: | ||
+ | |||
+ | // 要素の追加は make_pair を用いて行う | ||
+ | month_map.insert(std:: | ||
+ | month_map.insert(std:: | ||
+ | month_map.insert(std:: | ||
+ | // 同じキーに対応する要素は追加される | ||
+ | month_map.insert(std:: | ||
+ | | ||
+ | // あるキーに対応する値をすべて探索 | ||
+ | auto range = month_map.equal_range(3); | ||
+ | // equal_range の戻り値はキーが対応する最初と最後+1のイテレータの pair | ||
+ | // std:: | ||
+ | for ( auto itr = range.first; | ||
+ | std::cout << (*itr).second << std::endl; | ||
+ | } | ||
+ | // March | ||
+ | // San-gatsu | ||
+ | | ||
+ | std:: | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
===unordered_multimap=== | ===unordered_multimap=== | ||
- | std でも boost でもよい | + | 一般的には hash multimap と呼ばれる.\\ |
+ | キーの順番に従って並べられるわけではなく,キーから要素を取り出すことに特化したコンテナクラスとなっている(らしい). | ||
+ | std にも導入されているが,自分は | ||
unordered なコンテナを使う際には等号とハッシュ関数が必要.\\ | unordered なコンテナを使う際には等号とハッシュ関数が必要.\\ | ||
自作クラスについてはこれらを定義する必要がある.\\ | 自作クラスについてはこれらを定義する必要がある.\\ | ||
- | boost の unordered_multimap | + | それぞれの関数のオーバーロードの仕方は[[programming: |
- | hash の作り方 | + | |
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #include < | ||
+ | |||
+ | int main (int argc, char *argv[]) { | ||
+ | |||
+ | // linklet の実装. | ||
+ | // ただし実は MC の解析であれば unordered である必要はなかった. | ||
+ | boost:: | ||
+ | | ||
+ | std:: | ||
+ | for ( auto ilinklet : linklets ) { | ||
+ | if ( ilinklet.first > ilinklet.second ) | ||
+ | std:: | ||
+ | linklet.insert(std:: | ||
+ | } | ||
+ | // これで上流の basetrack を基準につながる下流の basetrack を高速で探索することが可能となった. | ||
+ | // ただし,実際には int ではなく,plate などで大小関係が決まった構造体を詰めている | ||
+ | | ||
+ | // ある basetrack からつながるすべての basetrack を列挙する. | ||
+ | int target = 100; | ||
+ | if ( linklet.find(target) != linklet.end() ) { | ||
+ | auto range = linklet.equal_range(target); | ||
+ | for ( auto itr = range.first; | ||
+ | std::cout << (*itr).second << std::endl; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | std:: | ||
+ | |||
+ | } | ||
+ | |||
+ | </ |