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

C++のSTL set(セット)における要素の挿入と削除の基本

C++のSTL(標準テンプレートライブラリ)に含まれる set コンテナは、重複しない要素を自動的にソートして管理する便利なデータ構造です。本記事では、setへの挿入削除の方法を、実際に動作するサンプルコードと出力例とともに詳しく解説します。

要素の挿入:insert()

STLのsetに要素を挿入するには、insert() 関数を使用します。insert() はオブジェクトへの参照を受け取り、その要素を適切な位置(自動的にソートされた状態を保つ位置)に追加します。

すでに同じ値がセット内に存在する場合、重複した挿入は行われず、セットの内容は変化しません。これがsetコンテナの大きな特徴です。

使用する主な関数

  • st.size() … セットの現在の要素数(サイズ)を返します。
  • st.insert() … セットに新しい要素を挿入します。

サンプルコード

#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<<"選択してください: ";
        cin>>c;
        switch(c) {
            case 1:
                cout<<"セットのサイズ: ";
                cout<<st.size()<<endl;
            break;
            case 2:
                cout<<"挿入する値を入力: ";
                cin>>i;
                st.insert(i);
            break;
            case 3:
                cout<<"イテレータによるセットの表示: ";
                for (it = st.begin(); it != st.end(); it++) {
                    cout << (*it)<<" ";
                }
                cout<<endl;
            break;
            case 4:
                exit(1);
            break;
            default:
                cout<<"無効な選択です"<<endl;
        }
    }
    return 0;
}

実行結果

1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 1
セットのサイズ: 0
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 2
挿入する値を入力: 4
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 2
挿入する値を入力: 6
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 2
挿入する値を入力: 8
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 2
挿入する値を入力: 10
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了

選択してください: 3
イテレータによるセットの表示: 4 6 8 10
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 4

終了コード: 1

出力結果を見ると、挿入した順序に関係なく、要素が常に昇順(4 → 6 → 8 → 10)に並んでいることが確認できます。これはsetが内部で自動的にソートを行うためです。

効率的な挿入:emplace()

emplace() も要素をセットに挿入するための関数ですが、insert() とは動作が異なります。emplace() はオブジェクトをその場で直接構築(in-place構築)するため、不要な一時オブジェクトのコピーが発生しません。その結果、特に大型のオブジェクトを扱う場合に、insert() よりも効率よく挿入できます。

使用する主な関数

  • st.size() … セットの現在の要素数を返します。
  • st.emplace() … オブジェクトを直接構築しながらセットに挿入します。

サンプルコード

#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<<"選択してください: ";
        cin>>c;
        switch(c) {
            case 1:
                cout<<"セットのサイズ: ";
                cout<<st.size()<<endl;
            break;
            case 2:
                cout<<"挿入する値を入力: ";
                cin>>i;
                st.emplace(i);
            break;
            case 3:
                cout<<"イテレータによるセットの表示: ";
                for (it = st.begin(); it != st.end(); it++) {
                    cout << (*it)<<" ";
                }
                cout<<endl;
            break;
            case 4:
                exit(1);
            break;
            default:
                cout<<"無効な選択です"<<endl;
        }
    }
    return 0;
}

実行結果

1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 1
セットのサイズ: 0
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 2
挿入する値を入力: 4
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 6
無効な選択です
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 2
挿入する値を入力: 6
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 2
挿入する値を入力: 7
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 2
挿入する値を入力: 8
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 3
イテレータによるセットの表示: 4 6 7 8
1.セットのサイズを表示
2.セットに要素を挿入
3.セットの中身を表示:
4.終了
選択してください: 4

終了コード: 1

この実行例では、存在しないメニュー番号「6」を選んだ際に「無効な選択です」と表示されるdefault処理の動作も確認できます。

要素の削除:erase()

セットから要素を削除するには、erase() 関数を使用します。erase() の引数には、次のいずれかを指定できます。

  • … 指定した値と一致する要素を削除します。
  • 位置(イテレータ) … 指定した位置にある要素を削除します。
  • 範囲(イテレータのペア) … 指定した範囲内のすべての要素をまとめて削除します。

使用する主な関数

  • st.size() … セットの現在の要素数を返します。
  • st.insert() … セットに要素を挿入します。
  • st.erase() … セットから要素を削除します。

サンプルコード

#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<<"選択してください: ";
        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<<"イテレータによるセットの表示: ";
                for (it = st.begin(); it != st.end(); it++) {
                    cout << (*it)<<" ";
                }
                cout<<endl;
            break;
            case 5:
                exit(1);
            break;
            default:
                cout<<"無効な選択です"<<endl;
        }
    }
    return 0;
}

実行結果

1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 1
セットのサイズ: 0
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 2
挿入する値を入力: 1
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 2
挿入する値を入力: 2
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 2
挿入する値を入力: 3
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 2
挿入する値を入力: 4
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 4
イテレータによるセットの表示: 1 2 3 4
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 3
削除する要素を入力: 2
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了

選択してください: 4
イテレータによるセットの表示: 1 3 4
1.セットのサイズを表示
2.セットに要素を挿入
3.セットから要素を削除
4.セットの中身を表示:
5.終了
選択してください: 5

終了コード: 1

このように、値「2」を削除した後の表示では、残りの要素「1 3 4」だけが出力されており、erase() が正しく機能していることがわかります。

まとめ

  • insert() … セットに要素を挿入する基本的な関数。オブジェクトのコピーが発生します。
  • emplace() … 要素をその場で直接構築して挿入するため、コピーのコストを抑えられます。
  • erase() … 値・位置・範囲を指定して要素を削除できます。
  • setは重複を許さず、常に要素をソートされた状態で保持します。

これらの操作を使いこなせるようになると、重複チェックや順序付きデータ管理など、さまざまな場面でsetコンテナを効果的に活用できるようになります。ぜひ実際にコードを実行して、動作を確認してみてください。

  1. C++ STLのsetコンテナでlower_bound()関数を使う方法

    C++ STLのsetコンテナには、lower_bound()という便利なメンバ関数が用意されています。この関数は、引数として渡した値kと等しい要素を指すイテレータを返します。もしkがset内に存在しない場合は、「kより大きい要素のうち最小のもの」、つまり直後の要素を指すイテレータを返します。 setは内部的に要素を常にソート済みの状態で保持しているため、lower_bound()は二分探索によってO(log n)の計算量で効率的に動作します。 アルゴリズム Begin 空のsetコンテナsを初期化する。 lower boundの値を指すためのイテレータを宣言する。 s

  2. C++ STLのset find()関数の使い方を解説

    C++ STLのsetコンテナにおけるfind()関数は、指定した要素を検索し、その要素を指すイテレータを返します。もし要素がセット内に存在しない場合は、最後の要素の直後の位置(つまりend()が返すイテレータ)を指す値が返されます。この関数の計算量はO(log n)であり、setが内部的に平衡二分探索木(赤黒木)で実装されているため、高速な検索が可能です。アルゴリズムBegin セットコンテナの要素を出力するための関数 printS() を定義する。 空のセットコンテナ s を初期化し、いくつかの要素を挿入する。 関数を呼び出して、セットコンテナの要素を出力する。