简介:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器 底层结构是用二叉树实现
set和multiset区别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
注意⚠️:只要包含了set头文件就可以使用multiset
set构造和赋值操作set
set(const set &st); //拷贝构造
set& operator=(const set &st); //重载等号操作符
#includeusing namespace std; #include void printSet(const set &s){ for(set ::const_iterator it = s.begin();it != s.end();it++){ cout << *it << " "; } cout < s1; //插入数据 只有insert方法 s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(20); s1.insert(40); //set容器的特点:所有的元素插入时会被自动排序 //set容器插入重复数据无用 每个元素只能出现一次 printSet(s1); set s2(s1); //拷贝构造 printSet(s2); set s3; s3 = s2; //等号赋值 printSet(s3); } int main() { test01(); return 0; }
输出结果:
set大小和交换10 20 30 40
10 20 30 40
10 20 30 40
size(); //返回容器中元素个数
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
注意⚠️:set容器并没有resize()函数 假如我们用resize把原先的容器扩展变长 resize会以零来填充 而set容器是不允许插入重复的值 所以问题出现在了这里
#includeusing namespace std; #include //set容器大小和交换 void printSet(const set &s){ for(set ::const_iterator it = s.begin();it != s.end();it++){ cout << *it << " "; } cout < s1; //插入数据 只有insert方法 s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(40); //打印容器 printSet(s1); //判断是否为空 if(s1.empty()){ cout << "s1为空" << endl; }else{ cout << "s1不为空" << endl; cout << "s1的元素个数为: " << s1.size() << endl; } set s2; s2.insert(9); s2.insert(99); s2.insert(999); cout << "交换前: " << endl; printSet(s1); printSet(s2); s1.swap(s2); cout << "交换后: " << endl; printSet(s1); printSet(s2); } int main() { test01(); return 0; }
输出结果:
set插入和删除10 20 30 40
s1不为空
s1的元素个数为: 4
交换前:
10 20 30 40
9 99 999
交换后:
9 99 999
10 20 30 40
insert(elem); //在容器中插入元素elem
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素 返回下个元素的迭代器
erase(beg, end); //删除区间内的所有元素 返回下一个元素的迭代器
erase(elem); //删除容器中值为elem的元素
#includeusing namespace std; #include void printSet(const set &s){ for(set ::const_iterator it = s.begin();it != s.end();it++){ cout << *it << " "; } cout < s1; //插入数据 只有insert方法 s1.insert(30); s1.insert(10); s1.insert(20); s1.insert(40); s1.insert(15); //遍历 printSet(s1); //删除 s1.erase(s1.begin()); //删除自动排序后的第一个元素10 printSet(s1); s1.erase(30); //删除重载版本 printSet(s1); //区间删除 s1.erase(s1.begin(),s1.end()); //相当于清空了 //清空 s1.clear(); //和上一行代码效果一样 } int main() { test01(); return 0; }
输出结果:
set查找和统计10 15 20 30 40
15 20 30 40
15 20 40
find(key); //查找key是否存在 存在则返回该键的迭代器 不存在则返回set.end();
count(key); //统计key的元素个数
#includeusing namespace std; #include void printSet(const set &s){ for(set ::const_iterator it = s.begin();it != s.end();it++){ cout << *it << " "; } cout < s1; //插入数据 只有insert方法 s1.insert(30); s1.insert(10); s1.insert(20); s1.insert(40); s1.insert(30); //遍历 printSet(s1); //通过迭代器去接收find的返回值 set ::iterator pos = s1.find(30); if(pos != s1.end()){ cout << "找到元素" << *pos << endl; }else{ cout << "未找到元素" << endl; } //统计元素30的个数 unsigned long num1 = s1.count(30); cout << "30的个数为: " << num1 << endl; //统计元素300 unsigned long num2 = s1.count(300); cout << "300的个数为: " << num2 << endl; //总结:对set而言 count统计的结果不是1就是0 因为set不允许出现重复数 } int main() { test01(); return 0; }
输出结果:
set和multiset区别10 20 30 40
找到元素30
30的个数为: 1
300的个数为: 0
1.set不可以插入重复的数据 而multiset可以
2.set插入数据的同时会返回插入结果 表示插入成功(等下会详细讲到)
3.multiset不会检测数据 因此可以插入重复数据
#includeusing namespace std; #include void printSet(const set &s){ for(set ::const_iterator it = s.begin();it != s.end();it++){ cout << *it << " "; } cout < s; //插入这个数据的时候会返回一个对组 //pair //第一个迭代器代表插入到哪里了 第二个bool表明是否插成功了 pair ::iterator, bool> ret = s.insert(10); //ret.second表明对组中的第二个数据bool if(ret.second){ cout << "第一次插入成功" << endl; }else{ cout << "第一次插入失败" << endl; } ret = s.insert(10); //第二次插入10 if(ret.second){ cout << "第二次插入成功" << endl; }else{ cout << "第二次插入失败" << endl; } } void test02(){ multiset ms; //multiset只会返回一个代迭器 没有bool来判断是否插入成功 //所以multiset是允许插入重复的数据的 ms.insert(10); ms.insert(10); //遍历multiset for(multiset ::iterator it = ms.begin();it != ms.end();it++){ cout << *it << " "; } cout << endl; } int main() { test01(); test02(); return 0; }
输出结果:
pair对组创建第一次插入成功
第二次插入失败
10 10
功能描述:成对出现的数据 利用对组可以返回两个数据
pair
pair
#includeusing namespace std; #include void test01(){ //第一种方式 pair p1("张三",25); cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl; //第二种方式 pair p2 = make_pair("李四", 40); cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl; } int main() { test01(); return 0; }
输出结果:
set容器排序-内置数据类型姓名:张三 年龄:25
姓名:李四 年龄:40
主要技术点:set容器默认排序从小到大 利用仿函数 可以改变排序规则
仿函数就是重载了()运算符
注意⚠️:已经insert完的数据是不能改变排序规则了 要想改变规则必须在插入前就通过仿函数改变排序规则
#includeusing namespace std; #include class MyCompare{ public: //重载()运算符 bool operator()(int v1, int v2){ //降序 return v1 > v2; } }; void printSet1(set &s){ for(set ::iterator it = s.begin();it !=s.end();it++){ cout << *it << " "; } cout << endl; } void printSet2(set &s){ for(set ::iterator it = s.begin();it !=s.end();it++){ cout << *it << " "; } cout << endl; } void test01(){ set s1; //插入的时候自动从小到大排序 s1.insert(30); s1.insert(10); s1.insert(20); s1.insert(15); printSet1(s1); //指定排序规则从大到小 //按照仿函数的排序规则 set s2; s2.insert(30); s2.insert(10); s2.insert(20); s2.insert(15); printSet2(s2); } int main() { test01(); return 0; }
输出结果:
set容器排序-自定义数据类型10 15 20 30
30 20 15 10
#includeusing namespace std; #include class Person{ public: Person(string name, int age){ this->name = name; this->age = age; } string name; int age; }; class comparePerson{ public: bool operator()(const Person &p1, const Person &p2){ //降序 return p1.age > p2.age; } }; void printSet1(set &s){ for(set ::iterator it = s.begin();it !=s.end();it++){ cout << "姓名:"<< it->name << " 年龄:" << it->age << endl; } cout << endl; } void test01(){ //自定义的数据类型 都会指定排序规则 //不然系统不知道按照什么排序 set s; Person p1("张三",18); Person p2("李四",40); Person p3("王五",28); s.insert(p1); s.insert(p2); s.insert(p3); printSet1(s); } int main() { test01(); return 0; }
输出结果:
姓名:李四 年龄:40
姓名:王五 年龄:28
姓名:张三 年龄:18



