set/multiset容器

17 篇文章 0 订阅

一 set/multiset容器基本概念

1.1 set容器基本概念

        Set的特性是。所有元素都会根据元素的键值自动被排序。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值。

        我们可以通过set的迭代器改变set元素的值吗?不行,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织。换句话说,set的iterator是一种const_iterator.

        set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。

1.2 multiset容器基本概念

        multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。

multiset示例代码:

void num_1(multiset<int> &p)    //打印类
{
    for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << "  ";
    }
    cout << endl;
}

int main(void)
{
    multiset<int> p;
    p.insert(1);
    p.insert(1);
    p.insert(9);
    p.insert(2);
    num_1(p);    //自动排列打印

set示例代码:

#include <iostream>
#include<set>

void num_1(set<int> &p)    //打印函数
{
    for (set<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << " ";
    }
    cout << endl;
}

int main(void)
{
    set<int> set1;
    set1.insert(19);
    set1.insert(2);
    set1.insert(13);   //set1不可以有重复的
    set1.insert(10);
    set1.insert(90);

    num_1(set1);

    if(set1.empty())
    {
        cout << "set1容器为空" << endl;
    }
    else{
        cout << "set1容器大小为: " << set1.size() << endl;
    }

    // set1.empty(19);

    set<int>::iterator pos = set1.find(2);  //find找,反回值是相应的迭代器
    if(pos == set1.end())
    {
        cout << "找到了" << *pos << endl;
    }
    else{
        cout << "没找到" << endl;
    }
    return 0;
}

set降序:

void num_1(multiset<int> &p)
{
    for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << "  ";
    }
    cout << endl;
}

class myCom   //伪函数
{
    public:
        bool operator()(const int v1,const int v2) const   //重载()
        {
            return v1 > v2;
        }
};

int main(void)
{
    set<int,myCom> set1;     //默认升序  底层认为myCon是一个类,所以函数就需要一个小括号
    //要在插入之前设置好
    set1.insert(19);
    set1.insert(2);
    set1.insert(13);   
    set1.insert(10);
    set1.insert(90);
    for(set<int,myCom>::iterator it = set1.begin();it != set1.end();it++)
    {
        cout << *it << endl;
    }

multiset代码:

void num_1(multiset<int> &p)
{
    for (multiset<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << "  ";
    }
    cout << endl;
}tiset

int main(void)
{
    multiset<int> p;
    p.insert(1);
    p.insert(1);
    p.insert(9);
    p.insert(2);
    num_1(p);

二 set常用API

2.1 set构造函数

底层:

set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数: 
set(const set &st);//拷贝构造函数

示例代码:

void num_1(set<int> &p)   //打印函数
{
    for (set<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << endl;
    }
    cout << endl;
}

int main()
{

    set<int> v; set默认构造函数:
    v.insert(1);
    v.insert(2);
    v.insert(3);

    set<int> v2(v); //拷贝构造函数
    num_1(v2);

        注意:这里拆入为什么不能使用 push_back()?

        set容器是一个有序且不重复的容器,在C++中实现为红黑树。这意味着set容器中的元素是按照某种顺序排列的,并且不能有重复的元素。

        而push_back是vector容器和deque容器中的成员函数,用于在容器的尾部插入元素。

        由于set容器是有序的,对于每个元素的插入都需要按照一定的规则来保持有序,因此需要使用set容器中的insert函数来插入元素,而不是push_back函数。

2.2 set赋值操作

底层:

set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器

示例代码:

void num_1(set<int> &p)   //打印函数
{
    for (set<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << endl;
    }
    cout << endl;
}

int main()
{

    set<int> v; set默认构造函数:
    v.insert(1);
    v.insert(2);
    v.insert(3);

    set<int> v2;
    v2 = v; // 重载等号操作符
    num_1(v2);

    v2.swap(v);  //交换

2.3 set大小操作

底层:

size();//返回容器中元素的数目
empty();//判断容器是否为空

示例代码:

int main()
{

    set<int> v; set默认构造函数:
    v.insert(1);
    v.insert(2);
    v.insert(3);

    cout << v.size() << endl; // 返回容器中元素的数目

    int a = v.empty(); // 判断容器是否为空
    if(a)  //为空返回 0 , 不为空返回 1;
    {
        cout << "v为空" << endl;
    }
    else
    {
        cout << "v不为空" << endl;
    }

2.4 set插入和删除操作

底层:

insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。

示例代码:

void num_1(set<int> &p)   //打印函数
{
    for (set<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << endl;
    }
    cout << endl;
}

int main()
{

    set<int> v; set默认构造函数:
    v.insert(1);
    v.insert(2); // 在容器中插入元素。
    v.insert(3);

    // v.clear(); //删除所有元素

    v.erase(v.begin());   //删除迭代器指向的元素
    num_1(v);

    v.erase(v.begin(), v.end());  //删除两个迭代器之间的所有元素

    v.erase(1); //删除数值是1 的元素

2.5 set查找操作

底层:

find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

示例代码:

void num_1(set<int> &p)   //打印函数
{
    for (set<int>::iterator a = p.begin(); a != p.end();a++)
    {
        cout << *a << endl;
    }
    cout << endl;
}

int main()
{

    set<int> v; set默认构造函数:
    v.insert(1);
    v.insert(2); // 在容器中插入元素。
    v.insert(3);
    v.insert(4);
    v.insert(5);

    set<int>::iterator a = v.find(2); // 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
    cout << *a << endl; //这里注意,a为迭代器,不能直接打印

    int b = v.count(1);
    cout << b << endl; // 查找键key的元素个数

    set<int>::iterator c = v.lower_bound(3); // 返回第一个key>=keyElem元素的迭代器。
    cout << *c << endl;

    set<int>::iterator d = v.upper_bound(2); // 返回第一个key>keyElem元素的迭代器。
    cout << *d << endl;

2.5.1 equal_range(keyElem)使用

        示例代码:

    pair<set<int>::iterator, set<int>::iterator> res = v.equal_range(3);
    if (res.first != v.end())   
    {
         cout << "equal_range中的lower_bound值为:" << *res.first << endl;
        
    }
    else
    {
        cout << "没找到" << endl;
        
    }
    if (res.second != v.end())  //判断迭代器是否指出去

    {
        cout << "equal_range中的upper_bound值为:" << *res.second << endl;
        
    }
    else 
    {
        cout << "没找到" << endl;
        
    }

equal_range返回值为两个迭代器:

  • range.first:指向第一个等于 的元素的迭代器。
  • range.second:指向第一个大于 的元素的迭代器。
  • 这里可以使用对组来处理pair。

三 对组(pair)

        对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有属性first和second访问。

        类模板:template <class T1, class T2> struct pair.

        如何创建对组?

//第一种方法创建一个对组
pair<string, int> pair1(string("name"), 20);
cout << pair1.first << endl; //访问pair第一个值
cout << pair1.second << endl;//访问pair第二个值
//第二种
pair<string, int> pair2 = make_pair("name", 30);
cout << pair2.first << endl;
cout << pair2.second << endl;
//pair=赋值
pair<string, int> pair3 = pair2;
cout << pair3.first << endl;
cout << pair3.second << endl;

对组的优点有以下几点:

  1. 对组可以同时存储不同类型的数据,比如上述代码中的 string 和 int 类型。
  2. 对组可以通过成员变量 first 和 second 访问其中的元素,不需要使用额外的数据结构或方法。
  3. 对组可以通过赋值操作符直接进行赋值,方便快捷。
  4. 对组可以使用 make_pair 函数来创建,简化了代码书写的过程。

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值