c++ 11标准模板(STL) std::set(九)

定义于头文件 <set>
template<

    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>

> class set;
(1)
namespace 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) 进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。

在每个标准库使用比较 (Compare) 概念的场所,用等价关系确定唯一性。不精确地说,若二个对象 ab 相互间既不比较大于亦不比较小于: !comp(a, b) && !comp(b, a) ,则认为它们等价。

std::set 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、关联容器 (AssociativeContainer) 和可逆容器 (ReversibleContainer) 的要求。

查找

返回匹配特定键的元素数量

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

size_type count( const Key& key ) const;

(1)

template< class K >
size_type count( const K& x ) const;

(2) (C++14 起)

 返回拥有关键比较等价于指定参数的元素数,因为此容器不允许重复故为 1 或 0。

1) 返回拥有关键 key 的元素数。

2) 返回拥有关键比较等价于值 x 的元素数。此重载仅若有限定 id Compare::is_transparent 合法且指代一个类型才参与重载决议。这允许调用此函数而不构造 Key 的实例。

参数

key - 要计量元素数的关键值
x - 要与关键比较的替用值

返回值

拥有比较等价于 keyx 的关键的元素数,对于 (1) 为 1 或 0。

复杂度

与容器大小成对数。

寻找带有特定键的元素

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

iterator find( const Key& key );

(1)

const_iterator find( const Key& key ) const;

(2)

template< class K > iterator find( const K& x );

(3) (C++14 起)

template< class K > const_iterator find( const K& x ) const;

(4) (C++14 起)

 1,2) 寻找键等于 key 的的元素。

3,4) 寻找键比较等价于值 x 的元素。此重载仅若若有限定 id Compare::is_transparent 合法并且指代类型才参与重载决议。允许调用此函数而无需构造 Key 的实例。

参数

key - 要搜索的元素键值
x - 能通透地与键比较的任何类型值

返回值

指向键等于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 end() )迭代器。

复杂度

与容器大小成对数。

返回匹配特定键的元素范围

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

std::pair<iterator,iterator> equal_range( const Key& key );

(1)

std::pair<const_iterator,const_iterator> equal_range( const Key& key ) const;

(2)

template< class K >
std::pair<iterator,iterator> equal_range( const K& x );

(3) (C++14 起)

template< class K >
std::pair<const_iterator,const_iterator> equal_range( const K& x ) const;

(4) (C++14 起)

 返回容器中所有拥有给定关键的元素范围。范围以二个迭代器定义,一个指向首个不小于 key 的元素,另一个指向首个大于 key 的元素。首个迭代器可以换用 lower_bound() 获得,而第二迭代器可换用 upper_bound() 获得。

1,2) 比较关键与 key

3,4) 比较关键与值 x 。此重载仅若有限定 id Compare::is_transparent 合法且指代一个类型才参与重载决议。它们允许调用此函数而不构造 Key 的实例。

参数

key - 要比较元素的关键值
x - 能与 Key 比较的替用值

返回值

含一对定义所需范围的迭代器的 std::pair :第一个指向首个不小于 key 的元素,第二个指向首个大于 key 的元素。

若无元素不小于 key ,则将尾后(见 end() )迭代器作为第一元素返回。类似地,若无元素大于 key ,则将尾后迭代器作为第二元素返回。

复杂度

与容器大小成对数。

返回指向首个不小于给定键的元素的迭代器

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

iterator lower_bound( const Key& key );

(1)

const_iterator lower_bound( const Key& key ) const;

(1)

template< class K >
iterator lower_bound(const K& x);

(2) (C++14 起)

template< class K >
const_iterator lower_bound(const K& x) const;

(2) (C++14 起)

 1) 返回指向首个不小于 key 的元素的迭代器。

2) 返回指向首个比较不小于x 的元素的迭代器。此重载仅若有限定 id Compare::is_transparent 合法并指代一个类型才参与重载决议。它们允许调用此函数而无需构造 Key 的实例。

参数

key - 要与元素比较的关键值
x - 能与 Key 比较的替用值

返回值

指向首个不小于 key 的元素的迭代器。若找不到这种元素,则返回尾后迭代器(见 end() )。

复杂度

与容器大小成对数。

返回指向首个大于给定键的元素的迭代器

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

iterator upper_bound( const Key& key );

(1)

const_iterator upper_bound( const Key& key ) const;

(1)

template< class K >
iterator upper_bound( const K& x );

(2) (C++14 起)

template< class K >
const_iterator upper_bound( const K& x ) const;

(2) (C++14 起)

 1) 返回指向首个大于 key 的元素的迭代器。

2) 返回指向首个比较大于x 的元素的迭代器。此重载仅若有限定 id Compare::is_transparent 合法并指代一个类型才参与重载决议。这允许调用此函数而无需构造 Key 的实例。

参数

key - 与元素比较的关键值
x - 能与 Key 比较的替用值

返回值

指向首个大于 key 的元素的迭代器。若找不到这种元素,则返回尾后(见 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()
{
    auto generate = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    std::set<Cell> set1{generate(), generate(), generate(), generate(), generate()};
    std::cout << "set1: ";
    std::copy(set1.begin(), set1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    for (std::set<Cell>::iterator it = set1.begin(); it != set1.end(); it++)
    {
        //1) 返回拥有关键 key 的元素数。
        std::cout << *it << "  count  "
                  << set1.count(*it) << std::endl;
    }

    std::cout << std::endl;


    std::set<Cell> set2{generate(), generate(), generate(), generate(), generate()};
    std::cout << "set2: ";
    std::copy(set2.begin(), set2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    for (std::set<Cell>::reverse_iterator rit = set2.rbegin(); rit != set2.rend(); rit++)
    {
        //寻找键等于 key 的的元素。
        std::set<Cell>::iterator fit = set2.find(*rit);
        std::cout << "set2 find " << *fit << std::endl;
    }

    std::cout << std::endl;


    std::set<Cell> set3{generate(), generate(), generate(), generate(), generate()};
    std::cout << "set3: ";
    std::copy(set3.begin(), set3.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    using PIT = std::pair<std::set<Cell>::iterator, std::set<Cell>::iterator>;
    for (std::set<Cell>::reverse_iterator rit = set3.rbegin(); rit != set3.rend(); rit++)
    {
        //返回容器中所有拥有给定关键的元素范围。
        PIT fit = set3.equal_range(*rit);
        std::cout << "set2 equal_range " << *rit << " --- ";
        for (std::set<Cell>::iterator it = fit.first; it != fit.second; it++)
        {
            std::cout << *it << " ";
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;


    std::set<Cell> set4{generate(), generate(), generate(), generate(), generate()};
    std::cout << "set4: ";
    std::copy(set4.begin(), set4.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    for (std::set<Cell>::iterator rit = set4.begin(); rit != set4.end(); rit++)
    {
        //1) 返回指向首个不小于 key 的元素的迭代器。
        std::set<Cell>::iterator fit = set4.lower_bound(*rit);
        std::cout << "set4 lower_bound " << *fit << std::endl;
    }

    std::cout << std::endl;


    std::set<Cell> set5{generate(), generate(), generate(), generate(), generate()};
    std::cout << "set5: ";
    std::copy(set5.begin(), set5.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    for (std::set<Cell>::iterator rit = set5.begin(); rit != set5.end(); rit++)
    {
        //1) 返回指向首个不小于 key 的元素的迭代器。
        std::set<Cell>::iterator fit = set5.upper_bound(*rit);
        std::cout << "set5 upper_bound " << *fit << std::endl;
    }
    return 0;
}

输出

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/130778674