您的位置:首页 > 编程语言 > C语言/C++

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

2018-01-12 16:46 337 查看
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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: