C++ Set/Multiset 常见用法全解(代码版)

set的特性是所有元素会根据元素的键值自动被排序。set不允许有两个元素有相同的键值。

set由红黑树作为底层结构。


set代码实例:

class struc{
public:
    struc(int a, int b): x(a), y(b){}
    int x;
    int y;
};

bool operator<(const struc& a, const struc& b)
{
    return a.y < b.y;
}

void set_test()     //不允许相同键值的存在
{
    //创建
    set<struc> st;
    
    //插入
    for (int i = 9; i >= 0; i--)
        st.insert(struc(i, i * 5));
    
    st.insert(struc(10, 40));   //添加失败,因为set有struc.y = 40的struc结构,是struc(8, 40)。主要是看比较函数中比较的是struc中的哪个值。
    st.insert(struc(9, 43));    //添加成功,因为set没有struc.y = 43的struc结构
    
    //查看
    for (auto it : st)
        cout<<it.x<<"-"<<it.y<<" ";                      //0-0 1-5 2-10 3-15 4-20 5-25 6-30 7-35 8-40 9-43 9-45
    cout<<endl;
    
    for (auto it = st.rbegin(); it != st.rend(); it++)   //9-45 9-43 8-40 7-35 6-30 5-25 4-20 3-15 2-10 1-5 0-0
        cout<<(*it).x<<"-"<<(*it).y<<" ";
    cout<<endl;
    
    //删除
    st.erase(st.begin());           //st.erase(st.begin() + 3)直接加3这种是不合法的
    st.erase(struc(2, 15));         //这句话会删除struct(3,15)。因为key值是y = 15。不管x是多少。
    
    for (auto it = st.begin(); it != st.end(); it++)    //1-5 2-10 4-20 5-25 6-30 7-35 8-40 9-43 9-45
        cout<<(*it).x<<"-"<<(*it).y<<" ";
    cout<<endl;
    
    //其他
    cout<<st.upper_bound(struc(3,5))->x<<endl;  //4  非递减序列中 大于 struc(3,5)的 第一个 迭代器。比大小依据的是operator<()中所比较的那个结构中的值
    cout<<st.lower_bound(struc(3,5))->x<<endl;  //15 非递减序列中 大于等于 struc(3,5)的 第一个 迭代器。比大小依据的是operator<()中所比较的那个结构中的值
    
    cout<<st.count(struc(9,40))<<endl;          //返回某个值元素的个数。
            //如果是自定义结构,比如struc(9,40)。如果比大小依据的是operator<()中所比较的那个结构中的值(struc.y),那就返回set中struc.y=40的个数。
            //在set中最多一个,因为struc.y = 40重复的struc结构是添加不进set的。
    
    auto it = st.find(struc(-1, 35));           //和上面一样,只会找y = 35的那一项。
    cout<<it->x<<" "<<it->y<<endl;              //7 35
    
    auto ret = st.equal_range(struc(-1, 40));   //返回集合中与给定值相等的上下限的两个迭代器 [)。找的是key值,这里面是y的升序。
    cout<<ret.first->y<<" "<<ret.second->y<<endl;
    
    st.empty();
    st.size();
    st.clear();
}


set另外两种自定义比较函数

    (1)元素不是结构体:

        例:

        //自定义比较函数myComp,重载()操作符

struct myComp

{

    bool operator()(const your_type &a, const your_type &b)

    {

        return a.data > b.data;

    }

}

set<int, myComp>s;


    (2)如果元素是结构体,可以直接将比较函数写在结构体内。

        例:

struct Info

{

    string name;

    float score;

    //重载“<”操作符,自定义排序规则

    bool operator < (const Info &a) const

    {

        //score从大到小排列

        return a.score < score;

    }

};

set<Info> s;



multiset代码实例:

class stru{
public:
    stru(int a, int b): x(a), y(b){}
    int x;
    int y;
};

bool operator<(const stru& a, const stru& b)    //比较的是x的值
{
    return a.x < b.x;
}

void multiset_test()
{
    //创建
    multiset<stru> st;
    
    //插入
    for (int i = 9; i >= 0; i--)
        st.insert(stru(i, i * 5));
    
    st.insert(stru(10, 40));   //添加成功,因为multiset可以有重复的值,也就是说有x = 10的stru也可以。
    st.insert(stru(9, 43));    //添加成功
    
    //查看
    for (auto it : st)
        cout<<it.x<<"-"<<it.y<<" ";                      //0-0 1-5 2-10 3-15 4-20 5-25 6-30 7-35 8-40 9-45 9-43 10-40
    cout<<endl;
    
    for (auto it = st.rbegin(); it != st.rend(); it++)   //10-40 9-43 9-45 8-40 7-35 6-30 5-25 4-20 3-15 2-10 1-5 0-0
        cout<<(*it).x<<"-"<<(*it).y<<" ";
    cout<<endl;
    
    //删除
    st.erase(st.begin());           //st.erase(st.begin() + 3)直接加3这种是不合法的
    st.erase(stru(2, 15));          //这句话会删除所有struct.x = 2的stru。不管y是多少。
    
    for (auto it = st.begin(); it != st.end(); it++)    //1-5 3-15 4-20 5-25 6-30 7-35 8-40 9-45 9-43 10-40
        cout<<(*it).x<<"-"<<(*it).y<<" ";
    cout<<endl;
    
    //其他
    cout<<st.upper_bound(stru(9,5))->y<<endl;  //10-40  非递减序列中 大于 stru(9,5)的 第一个 迭代器。比大小依据的是operator<()中所比较的那个结构中的值
    cout<<st.lower_bound(stru(9,5))->y<<endl;  //9-45 非递减序列中 大于等于 stru(9,5)的 第一个 迭代器。比大小依据的是operator<()中所比较的那个结构中的值
    
    cout<<st.count(stru(9,40))<<endl;          //2 返回某个值元素的个数。
    //如果是自定义结构,比如stru(9,40)。如果比大小依据的是operator<()中所比较的那个结构中的值(stru.x),那就返回multiset中struc.x = 9的个数。
    
    auto it = st.find(stru(9, 35));           //和上面一样,只会找x = 9的第一项。
    cout<<it->x<<" "<<it->y<<endl;            //9 45
    
    auto ret = st.equal_range(stru(9, 35));   //返回集合中与给定值相等的上下限的两个迭代器 [)。找的是key值,这里面是y的升序。
    cout<<ret.first->y<<" "<<ret.second->y<<endl;  //ret.first是9-45  ret.second是10-40
    
    st.empty();
    st.size();
    st.clear();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值