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/04/14 13:56] odagawa |
programming:cpp:container [2022/05/06 17:25] (current) odagawa |
||
|---|---|---|---|
| Line 16: | Line 16: | ||
| <code cpp> | <code cpp> | ||
| + | #include < | ||
| #include < | #include < | ||
| Line 72: | Line 73: | ||
| たとえば '' | たとえば '' | ||
| - | linklet は重複が考えられるが,重複する linklet を考える意味はなく,また順番よりもある linklet の有無が気になることがあるため. (もちろんアルゴリズムによる) | + | linklet は重複が考えられるが,重複する linklet を考える意味はなく,また順番よりもある linklet の有無が気になることがあるため. (もちろんアルゴリズムによる)\\ |
| + | なお,こんな長い型は本来は適当に以下のように typedef するべきである. | ||
| + | <code cpp> | ||
| + | typedef std:: | ||
| + | </ | ||
| set は二分木で探索する際に要素の順序を用いるため,少なくとも**不等号**が必要. (default は '' | set は二分木で探索する際に要素の順序を用いるため,少なくとも**不等号**が必要. (default は '' | ||
| - | 自作クラスについては'' | + | 自作クラスについては'' |
| + | operator のオーバーロードの仕方は[[programming: | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | int main (int argc, char *argv[]) { | ||
| + | |||
| + | std:: | ||
| + | |||
| + | // 要素の追加 | ||
| + | test_set.insert(1); | ||
| + | test_set.insert(2); | ||
| + | // 同じ要素は追加されない | ||
| + | test_set.insert(2); | ||
| + | // insert の戻り値は std:: | ||
| + | // first は追加された場合はその iterator を,そうでない場合はすでにその要素が存在する iterator を指す | ||
| + | // second は追加された場合は true を,そうでない場合は false を出力する | ||
| + | |||
| + | // 順番にソートされている | ||
| + | // ただし順番にしたいだけなら vector を sort したほうがよい | ||
| + | for ( auto itr = test_set.begin(); | ||
| + | std::cout << *itr << std:: | ||
| + | } | ||
| + | // 1 | ||
| + | // 2 | ||
| + | |||
| + | // 値が set に存在するかを確認 | ||
| + | if ( test_set.find(1) != test_set.end() ) | ||
| + | std::cout << " | ||
| + | else | ||
| + | std::cout << "Not found" << std:: | ||
| + | // Found | ||
| + | |||
| + | std:: | ||
| + | |||
| + | } | ||
| + | </ | ||
| ===map=== | ===map=== | ||
| Line 87: | Line 130: | ||
| たとえば '' | たとえば '' | ||
| これは ''< | これは ''< | ||
| - | |||
| - | 要素の追加には std:: | ||
| map は二分木で探索する際にキーの順序を用いるため,少なくとも**不等号**が必要. (default は '' | map は二分木で探索する際にキーの順序を用いるため,少なくとも**不等号**が必要. (default は '' | ||
| - | 自作クラスについては'' | + | 自作クラスについては'' |
| + | operator のオーバーロードの仕方は[[programming: | ||
| - | 例えば int と double をもつクラスをキーとして使う場合は, | + | <code cpp> |
| - | <code cpp MyClass.hpp> | + | #include < |
| - | #ifndef MYCLASS_HPP | + | #include <map> |
| - | #define MYCLASS_HPP | + | |
| - | class MyClass { | + | int main (int argc, char *argv[]) { |
| - | public : | + | |
| - | | + | |
| - | double var2; | + | |
| - | + | ||
| - | bool operator< | + | |
| - | }; | + | |
| - | #endif | + | std::map<int, std::string> month_map; |
| - | </code> | + | |
| - | + | // 要素の追加は make_pair を用いて行う | |
| - | <code cpp MyClass.cpp> | + | month_map.insert(std:: |
| - | # | + | |
| - | + | month_map.insert(std:: | |
| - | bool MyClass::operator< | + | // 同じキーに対応する要素は追加されない |
| - | | + | |
| - | | + | |
| - | | + | // キーの順番にソートされている |
| + | | ||
| + | | ||
| + | | ||
| + | // 1月 : January | ||
| + | // 2月 : February | ||
| + | // 3月 : March | ||
| + | |||
| + | // キーの値で月を探索 | ||
| + | std::string second_month = month_map.at(2); | ||
| + | std::cout << second_month << std:: | ||
| + | // February | ||
| + | |||
| + | std:: | ||
| + | | ||
| } | } | ||
| </ | </ | ||
| Line 123: | 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:: | ||
| + | |||
| + | } | ||
| + | |||
| + | </ | ||