set容器基本概念
所有元素都会在插入时自动被排序
set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
二者在使用的时候都仅需要包含一个set头文件即可。
set容器的构造和赋值
构造:
- set
st;//默认构造函数: - set(const set &st);//拷贝构造函数
赋值:
- set& operator=(const set &st);//重载等号操作符
#include<iostream>
using namespace std;
#include<set>
void print_set(set<int>st)
{
for (auto it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
set<int> st1;
//只有insert可以插入数据
st1.insert(30);
st1.insert(10);
st1.insert(10);
st1.insert(40);
st1.insert(20);
st1.insert(50);
print_set(st1);//10 20 30 40 50 自动排序去重
set<int>st2(st1);
print_set(st2);
set<int>st3;
st3 = st2;
print_set(st3);
}
int main()
{
test();
}set容器的大小和交换
统计set容器大小以及交换set容器
size();//返回容器中元素的数目
empty();//判断容器是否为空
swap(st);//交换两个集合容器
#include<iostream>
using namespace std;
#include<set>
void print_set(set<int>st)
{
for (auto it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
set<int> st1;
st1.insert(30);
st1.insert(10);
st1.insert(10);
st1.insert(40);
st1.insert(20);
st1.insert(50);
print_set(st1);
if (!st1.empty())
{
cout << "set不为空" << endl;
cout << "set的大小为" << st1.size() << endl;
}
else {
cout << "set为空" << endl;
}
set <int>st2;
st2.insert(100);
st2.insert(200);
st2.insert(300);
st2.insert(400);
cout << "交换前结果" << endl;
print_set(st1);
print_set(st2);
st1.swap(st2);
cout << "交换后结果" << endl;
print_set(st1);
print_set(st2);
}
int main()
{
test();
}set容器插入和删除
- insert(elem);//在容器中插入元素。
- clear();//清除所有元素
- erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
- erase(beg, end);//删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
- erase(elem);//删除容器中值为elem的元素。
#include<iostream>
using namespace std;
#include<set>
void print_set(set<int>st)
{
for (auto it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
set<int> st1;
st1.insert(30);
st1.insert(10);
st1.insert(10);
st1.insert(40);
st1.insert(20);
st1.insert(50);
print_set(st1);
st1.erase(st1.begin());
print_set(st1);
st1.erase(30);
print_set(st1);
//erase删除从头到尾,或者直接clear都可以清空
st1.erase(st1.begin(), st1.end());
st1.clear();
print_set(st1);
}
int main()
{
test();
}set容器的查找和删除
find(key);//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//统计key的元素个数
#include<iostream>
using namespace std;
#include<set>
void print_set(set<int>st)
{
for (auto it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
set<int> st;
st.insert(10);
st.insert(20);
st.insert(30);
st.insert(30);
st.insert(40);
st.insert(50);
set<int>::iterator pos = st.find(30);
if (pos != st.end())
{
cout << "找到元素:" << *pos << endl;
}
else {
cout << "没有找到元素" << endl;
}
int num = st.count(30);
cout << "num=" << num << endl;
}
int main()
{
test();
}对于set来说,count的值只会是0或者1,对于multiset可能是大于1的数。
set和multiset的区别
区别:
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
#include<iostream>
using namespace std;
#include<set>
void print_set(set<int>st)
{
for (auto it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test()
{
set<int>st;
pair<set<int>::iterator, bool> ret = st.insert(10);
if (ret.second)
{
cout << "第一次插入成功" << endl;
}
else {
cout << "第一次插入失败" << endl;
}
ret = st.insert(10);
if (ret.second)
{
cout << "第一次插入成功" << endl;
}
else {
cout << "第一次插入失败" << endl;
}
multiset <int>mt;
mt.insert(10);
mt.insert(10);
mt.insert(10);
for (multiset<int>::iterator it = mt.begin(); it != mt.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test();
}pair的创建
功能:成对出现的数据,利用对组可以返回两个数据
创建方式:
- pair<type,type> p(value1,value2);
- pair<type,type> p = make_pair(value1,value2);
#include<iostream>
using namespace std;
#include<string>
void test()
{
pair<string, int>p1("Tom", 18);
cout << "姓名:" << p1.first << "年龄:" << p1.second << endl;
pair<string, int> p2 = make_pair("Jerry", 23);
cout << "姓名:" << p2.first << "年龄:" << p2.second << endl;
}
int main()
{
test();
}set容器内置类型排序
set默认插入的数据是从小到大,我们也可以通过仿函数,让它从大到小排序
#include<iostream>
using namespace std;
#include<set>
void print_set(const set<int>& s)
{
for (auto it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
class Mycompare {
public:
bool operator()(int v1, int v2)const
{
return v1 > v2;
}
};
void test()
{
set<int>s1;
s1.insert(10);
s1.insert(30);
s1.insert(50);
s1.insert(40);
s1.insert(20);
print_set(s1);
set<int, Mycompare>s2;
s2.insert(10);
s2.insert(30);
s2.insert(50);
s2.insert(40);
s2.insert(20);
for (set<int, Mycompare>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test();
}set在插入的时候就已经排序了,所以我们在创建的时候就需要指定好规则,仿函数其实就是一个类,然后类里面这个函数后面要用const修饰才可以。
set容器自定义类型排序。
编译器不知道自定义数据类型怎么排序,自定义数据类型必须指定排序规则,否则插入会直接报错。一样是利用仿函数指定规则。
#include<iostream>
using namespace std;
#include<set>
#include<string>
class Person
{
public:
Person(string name, int age)
{
this->age = age;
this->name = name;
}
string name;
int age;
};
class mycompare {
public:
bool operator()(const Person& p1, const Person& p2)const
{
return p1.age < p2.age;
}
};
void test()
{
set<Person, mycompare>st;
Person p1("tom", 24);
Person p2("alice", 19);
Person p3("jack", 31);
Person p4("lily", 22);
Person p5("mike", 27);
Person p6("sophia", 20);
st.insert(p1);
st.insert(p2);
st.insert(p3);
st.insert(p4);
st.insert(p5);
st.insert(p6);
for (set<Person, mycompare>::iterator it = st.begin(); it != st.end(); it++)
{
cout << it->name << " " << it->age << endl;
}
}
int main()
{
test();
}