C++11 標準テンプレート (STL) std::set (6)

ヘッダー ファイル <set> で定義
テンプレート<

    クラス Key、
    クラス Compare = std::less<Key>、
    クラス Allocator = std::allocator<Key>

> クラスセット;
(1)
名前空間 pmr {

    template <class Key, class Compare = std::less<Key>>
    using set = std::set<Key, Compare, std::pmr::polymorphic_allocator<Key>>;

}
(2) (C++17以降)

std::setは、Keyタイプ の。並べ替えには比較機能Compare (Compare) を使用します。検索、削除、挿入には対数的な複雑さがあります。通常は、赤黒ツリーsetとして実装されます

標準ライブラリが比較の概念を使用するすべての場所で、一意性を決定するために等価関係が使用されます。正確には、2 つのオブジェクトaおよび がb互いに大きくも小さくもない場合、それらは同等であるとみなされます!comp(a, b) && !comp(b, a)

std::setContainerAllocatorAwareContainerAssociativeContainer 、およびReversibleContainerの要件を満たします

修飾子

要素またはノードを挿入する

std::set<Key,Compare,Allocator>::insert

std::pair<iterator,bool> insert( const value_type& value );

(1)

std::pair<iterator,bool> insert( value_type&& value );

(2) (C++11以降)

iterator insert( イテレータヒント, const value_type& value );

(3) (C++11まで)

iterator insert( const_iterator ヒント, const value_type& value );

(C++11以降)

iterator insert( const_iterator ヒント, value_type&& value );

(4) (C++11以降)

template< class InputIt >
void insert( 最初の InputIt、最後に InputIt );

(5)

void insert( std::initializer_list<value_type> ilist );

(6) (C++11以降)

insert_return_type insert(node_type&& nh);

(7) (C++17以降)

iterator insert(const_iterator ヒント、node_type&& nh);

(8) (C++17以降)

 

コンテナに同等のキーを持つ要素が含まれていない場合、要素をコンテナに挿入します。

1-2) を挿入しますvalue

3-4)位置の直前 (C++11 以降)valueできるだけ近くに挿入します。hint

5) range[first, last)から。範囲内の複数の要素に比較同等キーがある場合、どの要素が挿入されるかは指定されていません ( LWG2844保留中)。

6) ilistinitializer_list から要素を挿入します。範囲内の複数の要素に比較同等キーがある場合、どの要素が挿入されるかは指定されていません ( LWG2844保留中)。

7) が空のノード ハンドルnhの、何も行いません。それ以外の場合、コンテナに nh.key() と同等のキーを持つ要素がまだ含まれていない場合は、nhが所有する。nhnull以外でget_allocator() != nh.get_allocator() の場合、動作は未定義です。

8)nhが、何もせず、末尾の反復子を返します。それ以外の場合、コンテナーに nh.key() と等しいキーをnh持つし、 nh.key() と等しいキーを持つ要素を指す反復子を返します (挿入が成功しても失敗します)。挿入が成功した場合は からnh移動しますそうでない場合は要素の所有権を保持します。要素は、hintの。nhnull以外でget_allocator() != nh.get_allocator() の場合、動作は未定義です。

イテレータや参照は無効になりません。挿入が成功すると、ノードハンドルが要素を保持していた間に取得した要素へのポインタおよび参照は無効となり、抽出前に取得した要素へのポインタおよび要素への参照が有効になります。(C++17以降)

パラメータ

ヒント -
検索を開始する場所のヒントとして使用されるイテレータ (C++11まで)
新しい要素が挿入される前の位置を指す反復子 (C++11以降)
価値 - 挿入する要素の値
最初の最後 - 挿入する要素の範囲
から - 値が挿入されるinitializer_list
んー - 互換性のあるノードハンドル
タイプ要件
- LegacyInputIterator の要件InputItを満たす必要があります

戻り値

1-2) 挿入された要素 (または挿入を妨げた要素) を指す反復子と、挿入が行われた場合に true に設定されるブール値を返します。

3-4) 挿入された要素、または挿入を妨げた要素を指す反復子を返します。

5-6) (なし)

7) return insert_return_type、そのメンバーは次のように初期化されます: が空nhinsertedend ()、そして は空です。それ以外の場合、挿入が発生すると、挿入される要素指し、空になります。挿入が失敗した場合、は前の値を持ちnh.key() と同等のキーを持つ要素を指します。falsepositionnodeinsertedtruepositionnodeinsertedfalsenodenhposition

8) 空のnh場合は、挿入が発生した場合は挿入された要素への反復子、挿入が失敗した場合は nh.key() と同等のキーを持つ要素への反復子。

異常な

1-4) 操作で例外がスローされた場合、挿入は効果がありません。

このセクションは不完全です
理由: ケース 5 ~ 8

複雑さ

1-2) コンテナ サイズの対数、O(log(size()))

3-4) 挿入がヒントの直後に行われる場合は償却定数、それ以外の場合はコンテナーのサイズの対数。

(C++11まで)

3-4) ヒントの直前の位置で挿入が発生した場合は償却定数、それ以外の場合はコンテナ サイズの対数。

(C++11以降)

5-6)O(N*log(size() + N))ここで、N は挿入する要素の数です。

7) コンテナサイズの対数、O(log(size()))

8) 挿入がヒントの直前の位置で発生する場合、それは償却定数です。それ以外の場合、コンテナ サイズの対数になります。

知らせ

ヒント insert(3,4) は bool を返しません。これは、std::vector::insert シグニチャーなどの順次コンテナーでの位置指定挿入との互換性のためです。これにより、std::inserter などの汎用インサーターを作成できるようになります。ヒント付き挿入が成功したかどうかを確認する 1 つの方法は、挿入の前後で size() を比較することです。

オーバーロード (5、6) は通常、オーバーロード (3) が end() をヒントとして呼び出されるループとして実装されます。これらは、最大の要素よりも大きい最小の要素が追加された順序付けされたシーケンス (別のセットなど) を最適化します。 *これで。

電話の例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <set>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }


    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator >(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y > cell.y;
        }
        else
        {
            return x > cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

int main()
{
    std::cout << std::boolalpha;

    auto generate = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    std::set<Cell> set1;
    std::cout << "set1 is empty:   " << set1.empty() << std::endl;
    std::cout << std::endl;

    //插入元素到容器
    //1-2) 插入 value 。若容器拥有带等价关键的元素,则插入到范围上界。
    set1.insert(generate());
    std::cout << "set1:    ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    Cell cell = generate();
    // 移动语义
    set1.insert(std::move(cell));
    std::cout << "set1:    ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //3-4) 插入 value 到尽可能接近,正好前于(C++11 起) hint 的位置。
    set1.insert(set1.end(), generate());
    std::cout << "set1:    ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    set1.insert(set1.cend(), generate());
    std::cout << "set1:    ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    // 移动语义
    set1.insert(set1.cend(), std::move(cell));
    std::cout << "set1:    ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //5) 插入来自范围 [first, last) 的元素。
    std::set<Cell> set2{generate()};
    set2.insert(set1.begin(), set1.end());
    std::cout << "set2:    ";
    std::copy(set2.begin(), set2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //6) 插入来自 initializer_list ilist 的元素。
    std::set<Cell> set3{generate()};
    set3.insert({generate(), generate(), generate(), generate(), generate()});
    std::cout << "set3:    ";
    std::copy(set3.begin(), set3.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    return 0;
}

出力

 

おすすめ

転載: blog.csdn.net/qq_40788199/article/details/130660763