set关联式容器。set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构
set的常用方法:
添加元素:
insert()
删除元素:
clear() ,删除set容器中的所有的元素
erase()
查找元素:
set.find(…) ,查找元素位置并返回位置
begin() ,返回set容器的第一个元素
end() ,返回set容器的最后一个元素
set.count(5) ,统计集合中元素等于5的元素个数
empty() ,判断set容器是否为空
max_size() ,返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin ,返回的值和end()相同
rend() ,返回的值和rbegin()相同
1.添加元素和删除元素
//set元素的添加/遍历/删除基本操作
void Demo1()
{
set<int> Set;
for (int i = 0; i < 10; i++)
{
Set.insert(i + 1);//set集合没有push()函数,不能按照[]方式添加元素 ,只能用insert插入添加元素
}
Set.insert(100);//不能添加重复元素,元素唯一
Set.insert(100);
Set.insert(100);
for (set<int>::iterator it = Set.begin(); it != Set.end(); it++)
{
cout << *it << " ";//自动排序(默认情况下 是从小到大)
}
cout << endl;
//删除
while(!Set.empty())
{
Set.erase(Set.begin());
}
cout << Set.size() << endl;
}
2 对基本的数据类型 set能自动的排序
void Demo2()
{
set<int> set1;//从小到大(简写)
set<int, less<int>> set2; //默认情况下是这样 ,从小到大
set<int, greater<int>> set3; //从大 到 小
for (int i = 0; i < 10; i++)
{
set3.insert(rand());//随机插入整数
}
for (set<int, greater<int>>::iterator it = set3.begin(); it != set3.end(); it++)
{
cout << *it << " ";
}
}
3.自定义数据类型 排序
//03 仿函数 函数对象 重载() 操作 进行比较大小
//题目:学生包含学号,姓名属性,现要求任意插入几个学生对象到set容器中,使得容器中的学生按学号的升序排序
class student
{
public:
int age;
char *name;
student(int _age, char *_name)
{
age = _age;
name = _name;
}
void print()
{
cout << "age:" << age << " name:" << name << endl;
}
};
//伪函数
struct Function//伪函数一般使用struct,因为struct默认为public。如果用class的话必须标明是public类,因为class默认为private类型
{
bool operator()(const student &left, const student &right)//返回bool类型
{
if (left.age > right.age)//左边大返回true,从大到小排列
{
return true;
}
return false;
}
};
void Demo3()
{
student t1(22, "Christine22"), t2(23, "Christine23"), t3(24, "Christine24"),t4(24, "Christine24");
set<student, Function> set1;//对于类元素的排序,需要传入伪函数作为比较的函数,伪函数就是重载了函数()的结构体。第一个参数也应该改为传入自定义参数的类
set1.insert(t1);
set1.insert(t2);
set1.insert(t3);
set1.insert(t4);
for (set<student, Function>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << it->age << "\t " << it->name << " " << endl;
}
}
4.判断 set1.insert()函数是否插入成功
//typedef pair<iterator, bool> _Pairib;
//Pair的用法
void Demo4()
{
student t1(11, "Christine"), t2(23, "Christine"), t3(2654, "Christine"), t4(4, "Christine"), t5(11, "Christine");
set<student, Function> set1;
set1.insert(t1);
set1.insert(t2);
set1.insert(t3);
set1.insert(t4);
pair<set<student, Function>::iterator, bool> pair = set1.insert(t5);
if (pair.second==true)//通过判断pair返回的第二个值
{
cout << "插入t5成功" << endl;
}
else
{
cout << "插入t5失败" << endl;
}
}
5.find查找
//find查找 equal_range
//返回结果是一个pair
void Demo5()
{
set<int> set1;
for (int i = 0; i<10; i++)
{
set1.insert(i + 1);
}
for (set<int>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
set<int>::iterator it0 = set1.find(5);//查找元素5的位置
cout << "it0:" << *it0 << endl;
int num1 = set1.count(5);//统计集合中元素等于5的元素个数
cout << "num1:" << num1 << endl;
//算法lower_bound返回区间A的第一个迭代器,算法upper_bound返回区间A的最后一个元素的下一个位置,算法equal_range则是以pair的形式将两者都返回
set<int>::iterator it1 = set1.lower_bound(6); // 大于等于6的元素的 迭代器的位置
cout << "大于等于6的元素迭代器位置 it1:" << *it1 << endl;
set<int>::iterator it2 = set1.upper_bound(6); // 大于6的元素 的 迭代器的位置
cout << "大于6的元素的迭代器的位置 it2:" << *it2 << endl;
//把5元素删除掉
set1.erase(5);
for (set<int>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//算法lower_bound返回区间A的第一个迭代器,算法upper_bound返回区间A的最后一个元素的下一个位置,算法equal_range则是以pair的形式将两者都返回
pair<set<int>::iterator, set<int>::iterator> pair = set1.equal_range(6);//pair会返回两个迭代器,equal_range就是返回两个迭代器,第一个是大于等于,第二个是大于
set<int>::iterator it3 = pair.first;//从前往后找(第一个迭代器)
cout << "it3:" << *it3 << endl; //6
set<int>::iterator it4 = pair.second;//从后往前找(第二个迭代器)
cout << "it4:" << *it4 << endl; //7
}
multiset是可以将相同元素放进容器的容器,是set容器的补充(multiset相对于set而言可以存相同数据)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include "set"
void main10()
{
multiset<int> set1;//multiset相对于set而言可以存相同数据
int tmp = 0;
printf("请输入multiset集合的值:");
scanf("%d", &tmp);
while (tmp != 0)
{
set1.insert(tmp);
printf("请输入multiset集合的值:");
scanf("%d", &tmp);
}
//遍历
for (multiset<int>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
while (!set1.empty())
{
multiset<int>::iterator it = set1.begin();
cout << *it << " ";
set1.erase(it);
}
}