User Tools

Site Tools


programming:cpp:container

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
programming:cpp:container [2022/05/05 11:20]
odagawa
programming:cpp:container [2022/05/06 17:25] (current)
odagawa
Line 16: Line 16:
  
 <code cpp> <code cpp>
 +#include <iostream>
 #include <vector> #include <vector>
  
Line 81: Line 82:
 自作クラスについては''operator<'' を定義する必要がある.\\ 自作クラスについては''operator<'' を定義する必要がある.\\
 operator のオーバーロードの仕方は[[programming:cpp:class|ここ]]を参照. operator のオーバーロードの仕方は[[programming:cpp:class|ここ]]を参照.
 +
 +<code cpp>
 +#include <iostream>
 +#include <set>
 +
 +int main (int argc, char *argv[]) {
 +
 +  std::set<int> test_set;
 +  
 +  // 要素の追加
 +  test_set.insert(1);
 +  test_set.insert(2);
 +  // 同じ要素は追加されない
 +  test_set.insert(2);
 +  // insert の戻り値は std::pair<iterator, bool> になっている.
 +  // first は追加された場合はその iterator を,そうでない場合はすでにその要素が存在する iterator を指す
 +  // second は追加された場合は true を,そうでない場合は false を出力する
 +  
 +  // 順番にソートされている
 +  // ただし順番にしたいだけなら vector を sort したほうがよい
 +  for ( auto itr = test_set.begin(); itr != test_set.end(); itr++ ) {
 +    std::cout << *itr << std::endl;
 +  }
 +  // 1
 +  // 2
 +  
 +  // 値が set に存在するかを確認
 +  if ( test_set.find(1) != test_set.end() )
 +    std::cout << "Found" << std::endl;
 +  else
 +    std::cout << "Not found" << std::endl;
 +  // Found
 +  
 +  std::exit(0);
 +  
 +}
 +</code>
  
 ===map=== ===map===
Line 110: Line 148:
   month_map.insert(std::make_pair(3, "March"));   month_map.insert(std::make_pair(3, "March"));
   // 同じキーに対応する要素は追加されない   // 同じキーに対応する要素は追加されない
-  month_map.insert(std::make_pair(3, "April"));+  month_map.insert(std::make_pair(3, "San-gatsu"));
      
   // キーの順番にソートされている   // キーの順番にソートされている
Line 134: Line 172:
 C++ の reference は[[https://cpprefjp.github.io/reference/map/multimap.html|ここ]]にある.\\ C++ の reference は[[https://cpprefjp.github.io/reference/map/multimap.html|ここ]]にある.\\
 map において一つのキーに対して複数の要素を許すようにしたもの. map において一つのキーに対して複数の要素を許すようにしたもの.
 +
 +<code cpp>
 +#include <iostream>
 +#include <map>
 +
 +int main (int argv, char *argv[]) {
 +
 +  std::multimap<int, std::string> month_map;
 +
 +  // 要素の追加は make_pair を用いて行う
 +  month_map.insert(std::make_pair(1, "January"));
 +  month_map.insert(std::make_pair(2, "February"));
 +  month_map.insert(std::make_pair(3, "March"));
 +  // 同じキーに対応する要素は追加される
 +  month_map.insert(std::make_pair(3, "San-gatsu"));
 +  
 +  // あるキーに対応する値をすべて探索
 +  auto range = month_map.equal_range(3);
 +  // equal_range の戻り値はキーが対応する最初と最後+1のイテレータの pair
 +  // std::pair<iterator, iterator> である
 +  for ( auto itr = range.first; itr != range.second; itr++ ) {
 +    std::cout << (*itr).second << std::endl;
 +  }
 +  // March
 +  // San-gatsu
 +  
 +  std::exit(0);
 +
 +}
 +
 +</code>
  
 ===unordered_multimap=== ===unordered_multimap===
  
-std でも boost よい+一般的には hash multimap と呼ばれる.\\ 
 +キーの順番に従って並べられるわけはなく,キーから要素を取り出すことに特化したコンテナクラスとなっている(らしい). 
 +std に導入されているが,自分は boost のを使用した.
  
 unordered なコンテナを使う際には等号とハッシュ関数が必要.\\ unordered なコンテナを使う際には等号とハッシュ関数が必要.\\
 自作クラスについてはこれらを定義する必要がある.\\ 自作クラスについてはこれらを定義する必要がある.\\
-boost の unordered_multimap 例を以下に示す. +それぞれ関数オーバーロードは[[programming:cpp:class|ここ]]を参照.
-hash 作り+
  
 +<code cpp>
 +#include <iostream>
 +#include <vector>
 +#include <utility>
 +
 +#include <boost/unordered_map.hpp>
 +
 +int main (int argc, char *argv[]) {
 +
 +  // linklet の実装.
 +  // ただし実は MC の解析であれば unordered である必要はなかった.
 +  boost::unordered_multimap<int, int > linklet;
 +  
 +  std::vector<std::pair<int, int > > linklets;
 +  for ( auto ilinklet : linklets ) {
 +    if ( ilinklet.first > ilinklet.second )
 +      std::swap(ilinklet.first, ilinklet.second);
 +    linklet.insert(std::make_pair(linilet.first, linklet.second));
 +  }
 +  // これで上流の 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; itr != range.second; itr++ ) {
 +      std::cout << (*itr).second << std::endl;
 +    }
 +  }
 +
 +  std::exit(0);
 +
 +}
 +
 +</code>
programming/cpp/container.1651749644.txt.gz · Last modified: 2022/05/05 11:20 by odagawa