C++のstd::setの使い方について詳しく解説

std::setは重複を許さず、要素を自動的にソートしてくれるコンテナです。

本記事では、初心者でもわかりやすくstd::setの基本的な使い方を、サンプルコードを用いて解説していきます。

目次

std::setとは何か

std::setは、C++のSTL(Standard Template Library)に含まれるコンテナの一つです。

std::setは、要素を自動的にソートし、重複する要素を持たない集合を作ることができます。

std::setは、二分探索木(Binary Search Tree)と呼ばれるデータ構造を用いて実装されています。

このため、要素の挿入や削除、検索などの操作が高速に行える特徴があります。

また、std::setはイテレータをサポートしており、範囲ベースのforループなどで簡単に要素を取り出すことができます。

std::setの基本的な使い方

要素の追加

std::setに要素を追加する場合は、insert()関数を使用します。以下は、int型の値を格納するstd::setに要素を追加する例です。

#include <iostream>
#include <set>

int main()
{
    std::set<int> mySet;

    // 要素の追加
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(4);

    return 0;
}

上記の例では、mySetという名前のstd::set変数を宣言し、insert()関数で3, 1, 4という値を順番に追加しています。

要素の取得

std::setでは、様々な方法で要素を取得することができます。

#include <iostream>
#include <set>

int main() {
	std::set<int> myset = { 4, 2, 3, 1, 9, 5 };

	// 最初の要素を取得する
	auto it = myset.begin();
	std::cout << "最初の要素: " << *it << '\n';

	// 最後の要素を取得する
	it = myset.end();
	it--;
	std::cout << "最後の要素: " << *it << '\n';

	// 指定した値以上の最小の要素を取得する
	it = myset.lower_bound(2);
	std::cout << "2以上の数値の中で最小の値: " << *it << '\n';

	// 指定した値より大きい最小の要素を取得する
	it = myset.upper_bound(2);
	std::cout << "2超過の数値の中で最小の値: " << *it << '\n';

	for (auto it : myset) {
		std::cout << it << " ";
	}
}
最初の要素: 1
最後の要素: 9
2以上の数値の中で最小の値: 2
2超過の数値の中で最小の値: 3
1 2 3 4 5 9

様々な方法で要素を取得できますが、2番目の要素を取得したいからmySet[2]のように書くというのはできないので注意してください(std::setは配列ではありません)。

要素の削除

std::setから要素を削除する場合は、erase()関数を使用します。以下は、先ほど作成したmySetから値1を削除する例です。

#include <iostream>
#include <set>

int main()
{
    std::set<int> mySet;

    // 要素の追加
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(4);

    // 要素の削除
    mySet.erase(1);
    for (auto it : myset) {
		    std::cout << it << " ";
	  }
    return 0;
}
3 4

上記の例では、erase()関数で値が1の要素を削除しています。

要素の検索

std::setから特定の値が含まれているかどうか調べる場合は、find()関数を使用します。

以下は、先ほど作成したmySetから2が含まれているかどうか調べる例です。

#include <iostream>
#include <set>

int main()
{
    std::set<int> mySet;

    // 要素の追加
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(4);

   // 値2が含まれているか調べる
   if (mySet.find(2) != mySet.end()) {
       std::cout << "2 is found." << std::endl;
   } else {
       std::cout << "2 is not found." << std::endl;
   }

   return 0;
}
2 is not found.

上記の例では、find()関数で値2が含まれているかどうか調べています。今回の場合だと2が含まれていないので、2 is not found.と表示されます。

std::setの高度な使い方

イテレータの利用

std::setはイテレータをサポートしており、要素を順番に取り出すことができます。以下はイテレータを使用した例です。

#include <iostream>
#include <set>

int main() {
    std::set<int> mySet = {1, 2, 3, 4, 5};

    // イテレータを使用して全ての要素を表示する
    for (auto itr = mySet.begin(); itr != mySet.end(); ++itr) {
        std::cout << *itr << " ";
    }
    std::cout << std::endl;

    return 0;
}
1 2 3 4 5

また、範囲ベースのfor文であれば以下のように書くことも可能です。

for (auto it : mySet) {
    std::cout << it << " ";
}

先頭から終端まで順番にアクセスする場合はfor(auto it : mySet)のような書き方がおすすめです。

要素の範囲検索

std::setlower_bound()upper_bound()メソッドを提供しており、指定した値以上または以下の最初の要素を返します。以下はlower_bound()メソッドを使用した例です。

#include <iostream>
#include <set>

int main() {
    std::set<int> mySet = {1, 2, 3, 4, 5};

    auto itr = mySet.lower_bound(3);

    if (itr != mySet.end()) {
        std::cout << "Found: " << *itr << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }

    return 0;
}
Found: 3

要素の比較関数の指定

std:setではデフォルトでは昇順でソートされます。

ですが、降順に並び替えたい場合は、set変数を宣言する際にstd::greater<型名>を第二引数に指定します。

その際に比較関数オブジェクト(ファンクタ)を渡すことで実現可能です。 以下は降順で並び替えた例です。

#include<iostream>
//↓これが必要なので注意
#include<functional>
#include<set>

using namespace std;

int main() {

	multiset<int, std::greater<int>> mySet = { 3, 6, 4, 8, 1, 3 };

	for (auto it : mySet) {
		cout << it << " ";
	}
	return 0;
}
8 6 4 3 3 1

std::greaterfunctionalをインクルードしないと使えない点にだけ注意しましょう。インクルードを忘れるとエラーになります。

終わりに

C++のstd::setの基本的な使い方について、解説しました。

std::setは、要素の重複を許さず、自動的にソートされるため、データ管理に非常に便利です。

ぜひこの記事を参考にして、C++プログラミングのスキルアップに役立ててください。

目次