【C++】std::setの基本的な使い方

setはユニークな要素を格納する連想コンテナの1つです.連想コンテナとはキーと値のペアを保持するクラスを指し,setの場合はインデックスがキーとなります. setは二分木として実装されているため,キーから値をとりだすのがO(logN)と高速です. ただしvectorとは異なり要素がユニークである必要があるので,使用の際は用途に合っているか確認する必要があります. (例えばマイナンバーのように値が一意であることが保証されていればsetが適している.一方で名簿のように同姓同名の人が含まれるケースも考える場合にsetは使うべきでない)

setの使い方

基本的な使い方

  • 初期化:set<ValueType> 変数名;
  • 要素の追加:insert()関数を用いる
  • 要素の削除:erase()関数を用いる
  • 値の参照:イテレータや範囲for文を用いる
    二分木で実装されているため,vectorなどで用いられる[]演算子でのアクセスはできない.
  • 値の検索:
    • 値の一致する要素のiteratorを得るにはfind()関数を用いる
    • 値の一致する要素があるかのみを確認した場合はcount()関数を用いる(返り値は0 or 1)
#include <iostream>
#include <set>

using namespace std;

int main() {
  // 変数の宣言
  set<int> s;

  // 値を挿入
  s.insert(1);
  s.insert(2);
  s.insert(3);
  s.insert(4);
  s.insert(5);

  // 値を削除
  auto c = s.erase(5);  // 5は存在するのでeraseの結果1が返される
  c = s.erase(4);  // 4は存在するのでeraseの結果1が返される
  c = s.erase(5);  // 5は既に削除済みなので,eraseの結果0が返される

  // 値の参照
  // iteratorを使う場合
  auto iter = s.begin();  // iterの方はstd::set<ValueType>::iteratorであるが,通常autoで受ける
  cout << *iter << endl;  // 1
  cout << *(iter + 1) << endl;  // 2

  // 範囲for文を使う場合
  for (auto x : s) {
    cout << *x << endl;
  }

  // 値の検索
  auto find_iter = s.find(3);  // O(logN)で3を探索
  if (find_iter != s.end()) {
    cout << "Found" << endl;
  } else {
    cout << "Not found" << endl;
  }

  if (s.count(3)) {
    cout << "Found" << endl;
  } else {
    cout << "Not found" << endl;
  }
}

その他

  • bool empty():setの要素が空かを判定
  • size=t size():setのユニークな要素の数を返す
  • void clear():setの全要素を削除する
  • イテレータを使ってvectorをsetに変換することができる
  size_t size = s.size();
  cout << "size: " << size << endl;  // size: 3
   
  s.clear();
  bool isEmpty = s.empty();  // true

  vector<int> v{1, 2, 3, 4, 5, 3};
  set<int> converted_s(v.begin(), v.end());