【c++容器】之set和mutilset
2021/4/9 1:25:23
本文主要是介绍【c++容器】之set和mutilset,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、set基本概念
简介:
-
所有元素都会在插入时自动被排序
本质:
-
set/multiset属于关联式容器,底层结构是用二叉树实现。
关联式容器:插入时自动排好序
set和multiset区别:
-
set不允许容器中有重复的元素
-
multiset允许容器中有重复的元素
2、set构造和赋值
功能描述:创建set容器以及赋值
构造:
-
set<T> st;
//默认构造函数: -
set(const set &st);
//拷贝构造函数
赋值:
-
set& operator=(const set &st);
//重载等号操作符
#include <iostream> #include <set> using namespace std; /* 构造: set<T> st; //默认构造函数: set(const set &st);` //拷贝构造函数 赋值: set& operator=(const set &st); //重载等号操作符 */ //遍历 void printSet01(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; //插入数据的时候只有insert的方式 s1.insert(30); s1.insert(40); s1.insert(40); s1.insert(10); s1.insert(10); s1.insert(20); //遍历容器 //set容器的特点: //1 所有元素在插入的时候自动排序 //2 不允许插入重复的值 printSet01(s1); //输出是有序的,并且不重复 //拷贝构造 set<int> s2(s1); printSet01(s2); //输出是有序的,并且不重复 //赋值操作 set<int> s3; s3 = s2; printSet01(s3); //输出是有序的,并且不重复 } int main(int argc, int *argv[]) { test01(); system("pause"); return 0; }
总结:
-
set容器插入数据时用insert
-
set容器插入数据的数据会自动排序
3、set大小和交换
功能描述:
-
统计set容器大小以及交换set容器
函数原型:
-
size();
//返回容器中元素的数目 -
empty();
//判断容器是否为空 -
swap(st);
//交换两个集合容器
#include <iostream> #include <set> using namespace std; /* size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个集合容器 */ //遍历 void printSet02(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } //大小 void test02() { set<int> s1; s1.insert(10); s1.insert(40); s1.insert(30); s1.insert(20); printSet02(s1); if (!s1.empty()) { cout << "set的大小是:" << s1.size() << endl; } else { cout << "set为空" << endl; } } //交换 void test002() { set<int> s1; s1.insert(10); s1.insert(40); s1.insert(30); s1.insert(20); set<int> s2; s2.insert(100); s2.insert(400); s2.insert(300); s2.insert(200); s2.insert(700); cout << "交换前:" << endl; printSet02(s1); printSet02(s2); s1.swap(s2); //交换的大小可以不一样 cout << "交换后:" << endl; printSet02(s1); printSet02(s2); } int main(int argc, int *argv[]) { test02(); cout << "------------------------------" << endl; test002(); system("pause"); return 0; }
总结:
-
统计大小 --- size
-
判断是否为空 --- empty
-
交换容器 --- swap
4、set插入和删除
功能描述:
-
set容器进行插入数据和删除数据
函数原型:
-
insert(elem);
//在容器中插入元素。 -
clear();
//清除所有元素 -
erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。 -
erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 -
erase(elem);
//删除容器中值为elem的元素。
#include <iostream> #include <set> using namespace std; /* insert(elem); //在容器中插入元素。 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。 erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 erase(elem); //删除容器中值为elem的元素。 */ //遍历 void printSet03(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } void test03() { set<int>s1; s1.insert(10); s1.insert(30); s1.insert(40); s1.insert(20); printSet03(s1); //删除 s1.erase(s1.begin()); //迭代器 printSet03(s1); //删除的重载版本 s1.erase(30); //具体的数 printSet03(s1); //清空 //s1.erase(s1.begin(), s1.end()); s1.clear(); printSet03(s1); } int main(int argc, int *argv[]) { test03(); system("pause"); return 0; }
总结:
-
插入 --- insert
-
删除 --- erase
-
清空 --- clear
5、set查找和统计
功能描述:
-
对set容器进行查找数据以及统计数据
函数原型:
-
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(); -
count(key);
//统计key的元素个数
#include <iostream> #include <set> using namespace std; /* find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(); count(key); //统计key的元素个数 */ void test04() { set<int> s1; s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); s1.insert(30); //查找 set<int>::iterator pos = s1.find(10); //返回是迭代器 if (pos != s1.end()) { cout << "找到元素:" << (*pos) << endl; } else { cout << "没有找到该元素" << endl; } //统计 int count = s1.count(30); //对于set容器而言统计的结果无非是0或者1 cout << "count = " << count << endl; } int main(int argc, int* argv[]) { test04(); system("pause"); return 0; }
总结:
-
查找 --- find (返回的是迭代器)
-
统计 --- count (对于set,结果为0或者1)
6、set和multiset区别
-
掌握set和multiset的区别
区别:
-
set不可以插入重复数据,而multiset可以
-
set插入数据的同时会返回插入结果,表示插入是否成功
-
multiset不会检测数据,因此可以插入重复数据
(1)查看set.insert的源码
(a)
(b)
(c)
using _Pairib = pair<iterator, bool>; #vs201x typedef pair<iterator, bool> _Pairib; #vs2015
返回类型是pair:队组,第一个数据是迭代器,第二个数据是bool类型,表示成功或者失败
#include <iostream> #include <set> using namespace std; void test05() { set<int>s; pair<set<int>::iterator,bool> ret = s.insert(40); if (ret.second) { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } //再次插入 ret = s.insert(40); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } } int main(int argc, int *argv[]) { test05(); system("pause"); return 0; }
(2)查看multiset.insert的源码
(a)
返回类型是迭代器,不会判断
#include <iostream> #include <set> using namespace std; void test05() { //multiset multiset<int>ms; //允许插入重复的值 ms.insert(20); ms.insert(20); ms.insert(20); //遍历 for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) { cout << (*it) << " "; } cout << endl; } int main(int argc, int *argv[]) { test05(); system("pause"); return 0; }
总结:
-
如果不允许插入重复数据可以利用set
-
如果需要插入重复数据利用multiset
7、pair对组创建
功能描述:
-
成对出现的数据,利用对组可以返回两个数据
两种创建方式:
-
pair<type, type> p ( value1, value2 );
-
pair<type, type> p = make_pair( value1, value2 );
#include <iostream> #include <string> using namespace std; /* pair<type, type> p ( value1, value2 ); pair<type, type> p = make_pair( value1, value2 ); */ void test06() { pair<string, int> p("Tom", 10); cout <<"姓名:" <<p.first << " 年龄:" << p.second << endl; pair<string, int> p2 = make_pair("Jerry", 9); cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl; } int main(int argc, int *argv[]) { test06(); system("pause"); return 0; }
总结:
两种方式都可以创建对组,记住一种即可
8、set容器排序
-
set容器默认排序规则为从小到大,掌握如何改变排序规则
主要技术点:
-
利用仿函数,可以改变排序规则
内置类型排序
#include <iostream> #include <set> using namespace std; //内置数据类型排序 //仿函数 class MyCompare { public: //第一个() 重载() //第二个() 参数列表 //降序 bool operator()(int v1,int v2) { return v1 > v2; } }; void test07() { set<int>s1; s1.insert(40); s1.insert(20); s1.insert(50); s1.insert(10); s1.insert(30); for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { cout << (*it) << " "; } cout << endl; //指定排序规则 从大到小 //在没插入数据之前指定排序规则【利用仿函数】 set<int,MyCompare>s2; s2.insert(40); s2.insert(20); s2.insert(50); s2.insert(10); s2.insert(30); for (set<int>::iterator it = s2.begin(); it != s2.end(); it++) { cout << (*it) << " "; } cout << endl; } int main(int argc, int *argv[]) { test07(); system("pause"); return 0; }
总结:利用仿函数可以指定set容器的排序规则
自定义数据类型
#include <iostream> #include <set> #include <string> using namespace std; //自定义数据类型 排序 class Person { public: Person(string name, int age)// :m_Name(name), m_Age(age) { this->m_Age = age; this->m_Name = name; } string m_Name; int m_Age; }; //利用仿函数【注意顺序】 class ComparePerson { public: bool operator()(const Person& p1,const Person& p2) { //按照年龄 降序 return p1.m_Age > p2.m_Age; } }; void test08() { //自定义的数据类型会指定排序规则 set<Person, ComparePerson>s; Person p1("刘备", 24); Person p2("关羽", 22); Person p3("张飞", 21); Person p4("赵云", 20); s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); //遍历 for (set<Person, ComparePerson>::iterator it = s.begin(); it != s.end(); it++) { cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;; } } int main(int argc, int *argv[]) { test08(); system("pause"); return 0; }
总结:
对于自定义数据类型,set必须指定排序规则才可以插入数据
这篇关于【c++容器】之set和mutilset的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享