C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++ STL入門:setとunordered_setの違いを徹底解説

本記事では、C++ STLにおける setunordered_set の概要をわかりやすく解説し、両者の違いについても詳しく学んでいきます。

setとは?

set(セット)は、Key型の一意なオブジェクトをソート済みの状態で格納する連想コンテナです。各要素は一度しか出現できず、重複した値は許されません。ユーザーは任意の順序で要素を挿入してsetを作成できますが、setは常にソートされた形でデータを返します。つまり、setにはデータを並べ替えるための仕組みが内部に組み込まれており、その処理はユーザーから抽象化されています。

setを使うべき主なケースは以下の通りです。

  • ソート済みのデータが必要な場合
  • 重複値が不要で、一意なデータのみを扱いたい場合
  • ハッシュテーブルではなく二分探索木(Binary Search Tree)を利用したい場合
  • 検索時間が気にならない場合。検索の計算量はO(log n)です。

入力:

set = {2, 1, 5, 6, 9, 3, 2}

出力:

1, 2, 3, 5, 6, 9

ポイント: 値はランダムな順序で挿入されますが、setによって自動的にソートされ、さらに重複した値は削除されます。

サンプルコード

#include <iostream>
#include <set>
using namespace std;
int main(){
    // 配列の作成
    int arr[] = {2, 1, 5, 6, 9, 3, 2};
    int size = sizeof(arr)/ sizeof(arr[0]);
    // setの宣言
    set<int> SET;
    // insert() を使って配列からsetへ要素を挿入
    for(int i = 0; i<size; i++){
        SET.insert(arr[i]);
    }
    set<int>::iterator it;
    cout<<"set内の値: ";
    for(it = SET.begin(); it != SET.end(); it++){
        cout <<*it<<" ";
    }
}

実行結果

上記コードの出力は以下の通りです。

set内の値: 1 2 3 5 6 9

unordered_setとは?

unordered_setは、挿入された順序に関係なく、データを順不同の状態で格納する連想コンテナです。こちらも各要素は一度しか出現できず、重複した値は許されません。ユーザーは任意の順序で要素を挿入してunordered_setを作成できますが、返されるデータの順序は保証されません(つまり、順不同の形式で返されます)。

unordered_setを使うべき主なケースは以下の通りです。

  • ソートされたデータが不要で、順不同の形式でデータを扱ってよい場合
  • 重複値が不要で、一意なデータのみを扱いたい場合
  • 二分探索木ではなくハッシュテーブルを利用したい場合
  • より高速な検索が必要な場合。平均計算量はO(1)、最悪の場合はO(n)です。

入力:

set = {2, 1, 5, 6, 9, 3, 2}

出力:

3, 9, 6, 5, 2

サンプルコード

#include <iostream>
#include <unordered_set>
using namespace std;
int main(){
    int arr[] = { 2, 1, 5, 6, 9, 3, 2 };
    int size = sizeof(arr) / sizeof(arr[0]);
    unordered_set<int> U_SET;
    // insert() を使って配列からunordered_setへ要素を挿入
    for(int i = 0; i < size; i++){
        U_SET.insert(arr[i]);
    }
    unordered_set<int>::iterator it;
    cout << "unordered_set内の値: ";
    for(it = U_SET.begin(); it != U_SET.end(); it++){
        cout << *it << " ";
    }
}

実行結果

上記コードの出力は以下の通りです。

unordered_set内の値: 3 6 5 9 2 1

setとunordered_setの比較まとめ

最後に、両者の違いを表形式で整理しておきます。用途に応じて適切なコンテナを選択しましょう。

項目setunordered_set
内部構造二分探索木(赤黒木)ハッシュテーブル
要素の順序常にソート済み順序は不定
検索計算量O(log n)平均O(1)、最悪O(n)
重複要素許可されない許可されない

  1. C++のSTLでset_intersectionを実装し、2つの集合の積集合を求める方法

    2つの集合の積集合(インターセクション)とは、両方の集合に共通して含まれる要素だけを集めたものです。set_intersection関数によってコピーされる要素は、必ず最初の集合から取り出され、元の順序がそのまま維持されます。また、この関数を正しく動作させるためには、処理前に両方の集合がそれぞれソート済みである必要があります。 集合に対する代表的な操作には、以下のようなものがあります。 和集合(ユニオン) 積集合(インターセクション) 対称差(排他的論理和・XOR) 差集合(減算) アルゴリズム Begin   結果を格納するvector型変数vとイテレータstを宣言する。   st =

  2. 【C++】STLのset_differenceを使って2つの集合の差分を求める方法

    2つの集合の「差(差集合)」とは、1つ目の集合には存在するが、2つ目の集合には存在しない要素だけから構成される集合のことです。set_difference関数によってコピーされる要素は、必ず1つ目の集合から取り出され、元の順序が保たれます。また、この関数を正しく動作させるためには、両方の集合があらかじめソート(整列)されている必要があります。代表的な集合演算には以下のようなものがあります。和集合(Union)積集合(Intersection)対称差(Symmetric Difference / 排他的論理和)差集合(Difference / 減算)アルゴリズムBegin 集合用のvec