C++でSTLのset(セット)を実装・操作するサンプルプログラム
セット(set)は抽象データ型の一つで、各要素の値がその要素を識別するキーとなるため、すべての要素が一意(ユニーク)である必要があります。要素の値は、一度セットに追加すると変更できませんが、該当する要素を削除してから、変更後の値を新たに追加し直すことは可能です。
また、C++のstd::setは内部に平衡二分木(赤黒木)を使用しているため、要素は常に自動的にソートされた状態で保持され、挿入・削除・検索を対数時間 O(log n) で効率的に行えます。
使用する主なメンバ関数
st.size() : セットに格納されている要素数を返す
st.insert() : セットに新しい要素を挿入する
st.erase() : セットから指定した要素を削除する
st.find() : 検索した要素が見つかればその要素を指すイテレータを、
見つからなければ end() を返す
st.begin() : セットの先頭要素を指すイテレータを返す
st.end() : セットの末尾(最終要素の次)を指すイテレータを返すサンプルコード
以下は、メニュー形式でセットの基本操作(サイズ取得・挿入・削除・検索・表示)を試せるC++プログラムです。
#include <iostream>
#include <set>
#include <string>
#include <cstdlib>
using namespace std;
int main() {
set<int> st;
set<int>::iterator it;
int c, i;
while (1) {
cout << "1.セットのサイズ表示" << endl;
cout << "2.セットに要素を挿入" << endl;
cout << "3.セットから要素を削除" << endl;
cout << "4.セット内の要素を検索" << endl;
cout << "5.セットの内容を表示" << endl;
cout << "6.終了" << endl;
cout << "選択してください: ";
cin >> c;
switch (c) {
case 1:
cout << "セットのサイズ: ";
cout << st.size() << endl;
break;
case 2:
cout << "挿入する値を入力: ";
cin >> i;
st.insert(i);
break;
case 3:
cout << "削除する要素を入力: ";
cin >> i;
st.erase(i);
break;
case 4:
cout << "検索する要素を入力: ";
cin >> i;
it = st.find(i);
if (it != st.end())
cout << "要素 " << *it << " が見つかりました" << endl;
else
cout << "要素が見つかりませんでした" << endl;
break;
case 5:
cout << "イテレータによるセットの表示: ";
for (it = st.begin(); it != st.end(); it++) {
cout << (*it) << " ";
}
cout << endl;
break;
case 6:
exit(1);
break;
default:
cout << "無効な選択です" << endl;
}
}
return 0;
}実行結果
1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 1 セットのサイズ: 0 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 2 挿入する値を入力: 1 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 2 挿入する値を入力: 7 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 2 挿入する値を入力: 6 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 2 挿入する値を入力: 4 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 3 削除する要素を入力: 1 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 4 検索する要素を入力: 7 要素 7 が見つかりました 1.セットのサイズ表示 2.セットに要素を挿入 3.セットから要素を削除 4.セット内の要素を検索 5.セットの内容を表示 6.終了 選択してください: 6 終了コード: 1
プログラムのポイント
重複要素は自動的に排除される
insert()で既に存在する値を挿入しようとしても、セットには追加されず無視されます。このため、重複のないデータ集合を簡単に管理できます。
要素は常に昇順にソートされる
上記の例では 1、7、6、4 の順に挿入していますが、「5.セットの内容を表示」を選ぶと 4 6 7 のように昇順に出力されます。これはstd::setが内部的に木構造で要素を自動整列しているためです。
find() と end() の組み合わせ
要素の存在確認にはfind()を使い、戻り値がend()と等しいかどうかで判定します。end()は最終要素の次を指す特別なイテレータであり、これと一致した場合は目的の要素が存在しないことを意味します。
-
C++のSTLでset_intersectionを実装し、2つの集合の積集合を求める方法
2つの集合の積集合(インターセクション)とは、両方の集合に共通して含まれる要素だけを集めたものです。set_intersection関数によってコピーされる要素は、必ず最初の集合から取り出され、元の順序がそのまま維持されます。また、この関数を正しく動作させるためには、処理前に両方の集合がそれぞれソート済みである必要があります。 集合に対する代表的な操作には、以下のようなものがあります。 和集合(ユニオン) 積集合(インターセクション) 対称差(排他的論理和・XOR) 差集合(減算) アルゴリズム Begin 結果を格納するvector型変数vとイテレータstを宣言する。 st =
-
【C++】STLのset_differenceを使って2つの集合の差分を求める方法
2つの集合の「差(差集合)」とは、1つ目の集合には存在するが、2つ目の集合には存在しない要素だけから構成される集合のことです。set_difference関数によってコピーされる要素は、必ず1つ目の集合から取り出され、元の順序が保たれます。また、この関数を正しく動作させるためには、両方の集合があらかじめソート(整列)されている必要があります。代表的な集合演算には以下のようなものがあります。和集合(Union)積集合(Intersection)対称差(Symmetric Difference / 排他的論理和)差集合(Difference / 減算)アルゴリズムBegin 集合用のvec