一.特性
- 关联容器。
- 所以元素会根据元素的值自动进行排序。set是以RB-tree(红黑树是平衡二叉树的一种)为底层机制,其查找效率非常好。set容器不允许重复元素,multiset允许重复元素。
- 只有insert()方法。
- 不能用迭代器改变元素值,因为set集合值是有顺序的,改变值,会改变规则。
- 如果要改变元素值,必须先删除该结点,然后再插入。
set唯一性和排序性测试:
set<int> st;
st.insert(7);
st.insert(6);
st.insert(4);
st.insert(5);
st.insert(2);
st.insert(3);
st.insert(1);
st.insert(2);
st.insert(1);
st.insert(7);
for (int v : st) {
cout << v << " ";
}
二.构造函数
set<int> st;//set默认
multiset<int> mt;//multiset构造函数
set(const set & st);//拷贝构造函数
三.赋值操作
set& operator=(const set & st);//重载等号操作符
set<int> st, st1;
st.swap(st1);//交换两个集合容器
四.大小操作
set<int> st;
st.size();//返回容器中元素数目
st.empty();//判断容器是否为空
五.插入和删除
set<int> st;
st.insert(num);//在容器中插入元素
st.clear();//清楚所有元素
st.erase(pos);//删除pos迭代器所指向的元素,返回下一个元素的迭代器
st.erase(beg, end);//删除区间[beg,end)所有元素,返回下一个元素迭代器
st.erase(elem);//删除容器中值为elem的元素
六.查找操作
set<int> st;
st.find(key);//查找key是否存在,若存在,返回该键的元素迭代器,若不存在,返回map.end()
st.lower_bound(keyelem);//返回第一个key>=keyelem元素的迭代器
st.upper_bound(keyelem);//返回第一个key>keyelem元素的迭代器
st.equal_range(keyelem);//返回容器key与keyelem相等的上下限的两个迭代器
测试:
set<int> st;
st.insert(7);
st.insert(6);
st.insert(4);
st.insert(5);
st.insert(2);
st.insert(3);
st.insert(1);
st.insert(2);
st.insert(1);
st.insert(7);
for (int v : st) {
cout << v << " ";
}
cout << endl;
cout << "--------测试find()------" << endl;
set<int>::iterator it1 = st.find(4);
if (it1 == st.end()) {
cout << "没找到!" << endl;
}
else {
cout << "it1=" << *it1 << endl;
}
cout << "--------测试lower_bound(keyelem)()------" << endl;
set<int>::iterator it2 = st.lower_bound(4);
cout << "it2=" << *it2 << endl;
cout << "--------测试upper_bound(keyelem)()------" << endl;
set<int>::iterator it3 = st.upper_bound(4);
cout << "it3=" << *it3 << endl;
cout << "--------测试equal_range(keyelem)()------" << endl;
pair<set<int>::iterator,set<int>::iterator> mypair = st.equal_range(4);
if (mypair.first == st.end()) {
cout << "没有找到!" << endl;
}
else {
cout << *(mypair.first) << endl;
}
if (mypair.second == st.end()) {
cout << "没有找到!" << endl;
}
else {
cout << *(mypair.second) << endl;
}
结果:
七.更改默认排序
使用仿函数。
一定要注意仿函数书写!!!要加const
例子1:
仿函数
class mycompare {
public:
bool operator()(const int& v1,const int& v2) const{
return v1 > v2;
}
};
void test02() {
set<int,mycompare> st;//注意这里
st.insert(7);
st.insert(6);
st.insert(4);
st.insert(5);
st.insert(2);
st.insert(3);
st.insert(1);
st.insert(2);
st.insert(1);
st.insert(7);
for (int v : st) {
cout << v << " ";
}
}
结果:
例子2:
class Person {
public:
int id;
int age;
Person(int id,int age):id(id),age(age) {}
};
//仿函数
class mycompare2 {
public:
bool operator()(const Person& p1,const Person& p2) const{
return p1.age > p2.age;
}
};
void test03() {
set<Person, mycompare2> sp;
Person p1(10, 20), p2(30, 40), p3(50, 60);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
//遍历方法一:
for (Person v : sp) {
cout << "age=" << v.age << ",id=" << v.id << endl;
}
//遍历方法二:
}
结果:
八.查找问题
还是上面的代码:
由于set是按照age排序,因此,执行find()函数也是查找age。
在此,我们定义Person p4(30, 20),然后执行sp.find(p4)查看查找结果。
set<Person, mycompare2> sp;
Person p1(10, 20), p2(30, 40), p3(50, 60);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
//查找
Person p4(30, 20);
set<Person, mycompare2>::iterator it = sp.find(p4);
if (it == sp.end() ) {
cout << "不存在!" << endl;
}
else {
cout << "age=" << (*it).age << ",id=" << (*it).id << endl;
}
结果:发现查找出来的是p1的值,但是应该显示不存在才对。
原因:p4虽然不存在set中,但是p4.age=p1.age,所以自然查到p1的值。