STL -容器 <set> 相关API及原理
Set容器的基本概念
set的特性是:所有的元素都会根据元素的键值自动被排序(对于int来说默认从小到大)。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值
Set容器不能通过迭代器改变里面的值,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织,换句话说,set的iterator是一种const_iterator
set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
multiset容器基本概念
multiset特性及用法和set完全相同,唯一区别是允许键值重复,底层是用红黑树实现的。
API函数
构造函数
set<T> st //默认构造函数
multiset<T> mst
set(const set &st)
赋值操作
set &operator =(const set &set);
swap(st);
大小操作
size();
empty();
插入和删除操作
//没有push_back
insert(T) //在容器中插入元素 返回值为pair<set<T>::iterator ,bool> 可以查看second是否插入成功
clear()
erase(pos)
erase(beg,end)
erase(T)
查找操作(返回值都是迭代器,查找不到的内容则返回s.end() 结尾迭代器)
find(key) //查找键key是否存在,返回改元素的**迭代器**,若不存在则返回set.end()
count(key) //查找key的元素个数,对于set而言不是1就是0(因为元素不重复)
lower_bound(keyElem) //返回第一个个key>=keyElem元素的迭代器,若不存在则返回set.end()
upper_bound(keyElem) //返回第一个key>keyElem元素的迭代器,若不存在则返回set.end()
equal_range(keyElem) //返回容量中key与keyElem相等的上下限的两个迭代器(pair 对组类型)
代码
/*************************************************************************
> File Name: main.cpp
> Author: equal_range函数的测试
> Mail:
> Created Time: 2019年12月30日 星期一 15时48分14秒
************************************************************************/
# include<iostream>
# include <set>
using namespace std;
void PrintSet(const set<int> &s)
{
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
void test01()
{
set<int> s;
s.insert(5);
s.insert(2);
s.insert(21);
s.insert(20);
s.insert(55);
s.insert(23);
s.insert(6);
s.insert(0);
PrintSet(s);
/*
pair对组的两种创建方式
pair<string,int>p("Tom",123)
pair<string,int>p=make_pair("TOM",123)
*/
pair<set<int>::iterator,set<int>::iterator> ret = s.equal_range(2);
if(ret.first!=s.end())
{
cout<<"ret.first"<<*(ret.first)<<endl;
}
if(ret.second!=s.end())
{
cout<<"ret.second"<<*(ret.second)<<endl;
}
//结果会打印2 和 5
}
int main()
{
test01();
return 0;
}
利用仿函数修改set容器排序规则(从大到小)
/*************************************************************************
> File Name: main.cpp
> Author: 利用仿函数修改set容器的排序规则
> Mail:
> Created Time: 2019年12月30日 星期一 15时48分14秒
************************************************************************/
# include<iostream>
# include <set>
using namespace std;
class myCompare{
public:
bool operator()(int v1,int v2)
{
return v1>v2;
}
};
void PrintSet(const set<int,myCompare> &s)
{
for(set<int,myCompare>::iterator it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
void test01()
{
set<int,myCompare> s;
s.insert(5);
s.insert(2);
s.insert(21);
s.insert(20);
s.insert(55);
s.insert(23);
s.insert(6);
s.insert(0);
if(s.insert(0).second)
{
cout<<"插入成功"<<endl;
}else
cout<<"插入失败"<<endl;
PrintSet(s);
pair<set<int>::iterator,set<int>::iterator> ret = s.equal_range(2);
if(ret.first!=s.end())
{
cout<<"ret.first"<<*(ret.first)<<endl;
}
if(ret.second!=s.end())
{
cout<<"ret.second"<<*(ret.second)<<endl;
}
}
int main()
{
test01();
return 0;
}
运行结果:
/*************************************************************************
> File Name: main.cpp
> Author: 自定义数据类型插入set容器
> Mail:
> Created Time: 2019年12月30日 星期一 15时48分14秒
************************************************************************/
# include<iostream>
# include <set>
using namespace std;
class Person{
public:
Person(string name,int age)
{
this->name=name;
this->age=age;
}
string getName()const {return name;}
int getAge()const {return age;}
private:
string name;
int age;
};
class myCompare{
public:
bool operator()(const Person & v1,const Person& v2)
{
return v1.getAge()>v2.getAge();
}
};
void test01()
{
set<Person,myCompare> s;
Person s1("王宝强",44);
Person s2("黑色",20);
Person s3("打败",40);
s.insert(s1);
s.insert(s2);
s.insert(s3);
for(set<Person,myCompare>::iterator it=s.begin();it!=s.end();it++)
{
cout<<(*it).getName()<<" 年龄:"<<(*it).getAge()<<endl;
}
}
int main()
{
test01();
return 0;
}
运行结果:
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment