#include<iostream>
#include<algorithm>
#include<list>
#include<string>
#include<set>
using namespace std;
//使用set或者multiset的头文件都是se
//set的基本概念:
/*
Set的特性是。所有元素都会根据元素的键值自动被排序。(关联式容器自动排好序,序列式容器按插入顺序存放)
Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值。
我们可以通过set的迭代器改变set元素的值吗?
不行,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织。
换句话说,set的iterator是一种const_iterator.
set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,
在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
*/
//multiset容器基本概念:
/*
multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。
set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种。
*/
/*
set构造函数
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数
*/
/*
set赋值操作
set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
*/
/*
set插入和删除操作
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。
*/
void printSet(const set<int> &s)
{
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
set<int> s1;
s1.insert(5);
s1.insert(1);
s1.insert(9);
s1.insert(3);
s1.insert(7);
printSet(s1);
//size函数:
if (!s1.size()) {
cout << "s1为空" << endl;
}
else {
cout << "s1不为空" << endl;
}
//删除操作:
s1.erase(s1.begin());//还剩3.5.7.9
printSet(s1);
s1.erase(3);//5.7.9,删除这个数;
printSet(s1);
}
/*
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 test02()
{
//对于set,没有value和key之分;key==value;
set<int> s1;
s1.insert(5);
s1.insert(1);
s1.insert(9);
s1.insert(3);
s1.insert(7);
//查找操作:
set<int>::iterator pos = s1.find(3);//在set中查找3这个数;
if (pos != s1.end()) {
cout << "找到了这个数,这个数是:" << *pos << endl;
}
else {
cout << "没找到" << endl;
}
pos = s1.find(2);//在set中查找2这个数;
if (pos != s1.end()) {
cout << "找到了这个数,这个数是:" << *pos << endl;
}
else {
cout << "没找到" << endl;
}
//count(key);//查找键key的元素个数
//对于set而言,结果就是0或1;
int num = s1.count(1);
cout << "1的个数为: " << num << endl;//输出1
num = s1.count(2);
cout << "2的个数为: " << num << endl;//输出0
//lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
set<int>::iterator it = s1.lower_bound(3);
if (it != s1.end()) {
cout << "第一个>=3的元素是: " << *it << endl;
}
else {
cout << "未找到" << endl;
}
//upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
set<int>::iterator it_1 = s1.upper_bound(3);
if (it_1 != s1.end()) {
cout << "第一个>3的元素是: " << *it_1 << endl;
}
else {
cout << "未找到" << endl;
}
//equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
//上下限,一个是lower_bound,一个是upper_bound;
//返回值为:_NODISCARD _Paircc
//using _Paircc = pair<const_iterator, const_iterator>;
//pair;
pair<set<int>::iterator, set<int>::iterator> ret=s1.equal_range(3);
//获取第一个值:
if (ret.first == s1.lower_bound(3)) {
cout << "找到了下限:" << *(ret.first) << endl;
}
else {
cout << "没有找到下限" << endl;
}
if (ret.second == s1.upper_bound(3)) {
cout << "找到了上限:" << *(ret.second) << endl;
}
else {
cout << "没有找到上限" << endl;
}
}
//补充:对组的概念:
/*
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有属性first和second访问。
类模板:template <class T1, class T2> struct pair.
*/
void test03()
{
//创建方式一:
pair<string, int> P1 ("Tom", 100);
//取值:
cout << (P1.first)<< endl;
cout << (P1.second) << endl;
//与上面不同,上面的pair创建的是迭代器(指针);
//创建方式二:
pair<string, int>p2 = make_pair("Jerry", 99);
cout << p2.first << endl;
cout << p2.second << endl;
}
//set不允许插入重复的key值:
//multiset允许插入重复值:
void test04()
{
set<int> s;
s.insert(10);
s.insert(10);
printSet(s);//可以编译成功并运行,只是显示的只有一个10;
//insert的源码:
//_Pairib insert(value_type&& _Val)
//using _Pairib = pair<iterator, bool>;
//bool表示插入是否成功;
//有以下:
set<int> s2;
pair<set<int>::iterator, bool>ret = s2.insert(10);
if (ret.second) {
cout << "插入成功" << endl;
}
else {
cout << "插入失败" << endl;
}
//插入成功
printSet(s2);
ret = s2.insert(10);
if (ret.second) {
cout << "插入成功" << endl;
}
else {
cout << "插入失败" << endl;
}
//插入失败
printSet(s2);
ret = s2.insert(20);
if (ret.second) {
cout << "插入成功" << endl;
}
else {
cout << "插入失败" << endl;
}
//插入成功
printSet(s2);
}
//指定set的排序规则:
//仿函数:
//函数不能做类型,class可以做类型;
class myCompare
{
public:
//重载():
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};
void printSet_2(const set<int ,myCompare> &s)
{
for (set<int, myCompare>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
//set排序:
void test05()
{
set<int> s1;
s1.insert(5);
s1.insert(1);
s1.insert(9);
s1.insert(3);
s1.insert(7);
printSet(s1);
//从小到大排序;
//从大到小排序:
//set在数据插入后不允许改变,所以只能在插入之前确定排序顺序;
set<int, myCompare> s2;
s2.insert(5);
s2.insert(1);
s2.insert(9);
s2.insert(3);
s2.insert(7);
printSet_2(s2);
}
//set插入自定义数据类型:
class Person
{
public:
Person(string name,int age) :m_Name(name),m_Age(age){}
string m_Name;
int m_Age;
};
class myCompare_2
{
public:
bool operator()(const Person &p1,const Person &p2)
{
return p1.m_Age > p2.m_Age;
}
};
void test06()
{
Person p1("asdasd", 100);
Person p2("asd", 12130);
Person p3("asd\sdasd", 140);
Person p4("asdsadasdasd", 2340);
set<Person,myCompare_2> s;
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);
//打印:
for (set<Person, myCompare_2>::iterator it = s.begin(); it != s.end(); it++) {
cout << "姓名是:" << it->m_Name << " 年龄是:" << it->m_Age << endl;
}
}
int main()
{
test01();
test02();
test03();
test04();
test05();
test06();
system("pause");
return 0;
}
STL-----set容器的操作以及pair
猜你喜欢
转载自blog.csdn.net/XUCHEN1230/article/details/86549320
今日推荐
周排行