User Tools

Site Tools


programming:cpp:container

This is an old revision of the document!


コンテナクラス

STL のコンテナクラスを使いこなせれば処理が楽になることは往々にしてある.
時間があれば適切なコンテナクラスを使うことに挑戦してみるのがよい

以下は自分が使ったもの

vector

C++ の reference はここにある.
要素の順序を保存するクラスであり,要素数が自動的に拡張される一次元配列のイメージ.
添字によるランダムアクセスが高速で行なえ,配列の最後尾に要素を追加していくイメージで使用することが多い.
末尾以外への挿入がメインの操作であったり,シーケンシャルアクセスの速さが必要な場合は list や deque を使うらしい.

for loop の回し方を以下に示しておく.

#include <vector>
 
int main(){
 
  std::vector<int> v = {1, 3, 4};
 
  for ( auto iv : v ) {
    std::cout << iv << std::endl;
  }
  // 1
  // 3
  // 4
  v.push_back(5);
 
  for ( auto itr = v.begin(); itr != v.end(); itr++ ) {
    std::cout << *itr << std::endl;
  }
  // 1
  // 3
  // 4
  // 5
 
  v.at(0) = 0;
 
  for ( int i = 0; i < v.size(); i++ ) {
    std::cout << v.at(i) << std::endl;
  }
  // 0
  // 3
  // 4
  // 5
 
  std::cout << v.front << ", " << v.back << std::endl;
  // 0, 5
 
}

その他resize, empty, reserve, clear, shrink_to_fit などの使い方を調べてみるとよい.

array

C++ の reference はここにある.
要素の順序を保存するクラスであり,vector と違って要素数が決まっている.
個人的には vector を使っていればよいと思うので,あまり使っていない.
ROOT では array はバグの温床なので使わないほうがよい.

set

C++ の reference はここにある.
数学における集合に相当し,ユニークな要素を収納するクラス.
ある要素があるかないか」という特徴から探索をすることに特化しており,次の map において要素自身がキーとなっていることに相当する.
「コンテナの何番目」という特徴から探すのであれば vector や array がよい.
要素はユニークでなければならず,複数の要素を許すには multiset を用いる.

たとえば std::set<std::pair<B2EmulsionSummary*, B2EmulsionSummary* > > linklets としてあるグループに含まれる linklet の set を使った.
linklet は重複が考えられるが,重複する linklet を考える意味はなく,また順番よりもある linklet の有無が気になることがあるため. (もちろんアルゴリズムによる)

set は二分木で探索する際に要素の順序を用いるため,少なくとも不等号が必要. (default は less<Key>)
自作クラスについてはoperator< を定義する必要がある.

map

C++ の reference はここにある.
ユニークな要素をキーと関連付けて収納するクラス.
要素に対して「あるキーを持っている」という特徴から探索をすることに特化したコンテナクラス.
「コンテナの何番目」という特徴から探すのであれば vector や array がよい.
キーと要素は 1:1 対応でなければならず,あるキーに対して複数の要素を許すには multimap を用いる.

たとえば std::map<int, B2TrackSummary* > track_id_map として track id と B2 class の map を使った.
これは track->GetTrackId() とは別の id が emulsion 側とのインターフェースのために振られているためで,解析のフローを改良するべきだという意見は大いにある.

map は二分木で探索する際にキーの順序を用いるため,少なくとも不等号が必要. (default は less<Key>)
自作クラスについてはoperator< を定義する必要がある.

例えば int と double をもつクラスをキーとして使う場合は,

MyClass.hpp
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
 
class MyClass {
public : 
  int var1;
  double var2;
 
  bool operator<(const MyClass &rhs) const;
};
 
#endif
MyClass.cpp
#include "MyClass.hpp"
 
bool MyClass::operator<(const MyClass &rhs) const {
  if ( var1 != rhs.var1 )
    return var1 < rhs.var1;
  return var2 < rhs.var2
}

unordered_multimap

std でも boost でもよい

unordered なコンテナを使う際には等号とハッシュ関数が必要.
自作クラスについてはこれらを定義する必要がある.
boost の unordered_multimap の例を以下に示す. hash の作り方

programming/cpp/container.1649846432.txt.gz · Last modified: 2022/04/13 10:40 by odagawa