set容器
Posted chasemeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了set容器相关的知识,希望对你有一定的参考价值。
一.摘要
简介:
- 所有元素都会在插入时自动被排序
本质:
- set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
二.构造函数
函数原型:
set<T> st; //默认构造函数: set(const set &st); //拷贝构造函数
示例代码:
1 /*set构造函数*/ 2 #include<iostream> 3 #include<ctime> 4 #include<set> 5 using namespace std; 6 void printSet(set<int>&s) { 7 cout << "set:"; 8 for (set<int>::iterator it = s.begin(); it != s.end(); it++) { 9 cout << *it << " "; 10 } 11 cout << endl; 12 } 13 void printMultiset(multiset<int>&s) { 14 cout << "multiset:"; 15 for (set<int>::iterator it = s.begin(); it != s.end(); it++) { 16 cout << *it << " "; 17 } 18 cout << endl; 19 } 20 int main() { 21 int tmp; 22 srand((unsigned)time(NULL)); 23 set<int>s1; //set<T> st; //默认构造函数: 24 multiset<int>ms1; 25 for (int i = 0; i < 5; i++) { 26 tmp = rand(); 27 //set不可以添加重复数据,multiset可以添加重复数据 28 s1.insert(tmp); 29 s1.insert(tmp);//插两次 30 ms1.insert(tmp); 31 ms1.insert(tmp);//插两次 32 } 33 printSet(s1); 34 printMultiset(ms1); 35 set<int>s2(s1); //set(const set &st); //拷贝构造函数 36 multiset<int>ms2(ms1); 37 printSet(s2); 38 printMultiset(ms2); 39 system("pause"); 40 return 0; 41 }
运行结果:
二.大小和交换
函数原型:
size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个集合容器
示例代码:
1 /*set大小和交换*/ 2 #include<iostream> 3 #include<ctime> 4 #include<set> 5 using namespace std; 6 void printSet(set<int>&s) { 7 for (set<int>::iterator it = s.begin(); it != s.end(); it++) { 8 cout << *it << " "; 9 } 10 cout << endl; 11 } 12 int main() { 13 srand((unsigned)time(NULL)); 14 set<int>s1; 15 for (int i = 0; i < 5; i++) { 16 s1.insert(rand()); 17 } 18 if (s1.empty()) { //empty(); //判断容器是否为空 19 cout << "s1为空!"; 20 } 21 else { 22 cout << "s1不为空!" << endl; 23 cout << "s1的大小为:" << s1.size() << endl; //size(); //返回容器中元素的数目 24 } 25 cout << "s1:"; 26 printSet(s1); 27 set<int>s2; 28 for (int i = 0; i < 5; i++) { 29 s2.insert(rand()); 30 } 31 cout << "s2:"; 32 printSet(s2); 33 s1.swap(s2); //swap(st); //交换两个集合容器 34 cout << "交换后:" << endl; 35 cout << "s1:"; 36 printSet(s1); 37 cout << "s2:"; 38 printSet(s2); 39 system("pause"); 40 return 0; 41 }
运行结果:
二.插入和删除
函数原型:
insert(elem); //在容器中插入元素。 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。 erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 erase(elem); //删除容器中值为elem的元素。
示例代码:
1 /*set容器的插入和删除*/ 2 #include<iostream> 3 #include<ctime> 4 #include<set> 5 using namespace std; 6 void printSet(set<int>&s){ 7 for (set<int>::iterator it = s.begin(); it != s.end(); it++) { 8 cout << *it << " "; 9 } 10 cout << endl; 11 } 12 int main() { 13 srand((unsigned)time(NULL)); 14 set<int>s1; 15 for (int i = 0; i < 10; i++) { 16 s1.insert(rand()); //insert(elem); //在容器中插入元素。 17 } 18 s1.insert(18888); //插入一个18888 19 printSet(s1); 20 s1.erase(s1.begin()); //erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。 21 cout << "删除第一个元素之后:" << endl; 22 printSet(s1); 23 s1.erase(18888); //erase(elem); //删除容器中值为elem的元素。 24 cout << "删除set容器中的18888之后:" << endl; 25 printSet(s1); 26 s1.erase(++s1.begin(), --s1.end()); //erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 27 cout << "删除第二到倒数第一个元素之后" << endl; 28 printSet(s1); 29 s1.clear(); //clear(); //清除所有元素 30 cout << "清除所有元素之后:" << endl; 31 printSet(s1); 32 system("pause"); 33 return 0; 34 }
运行结果:
二.查找和统计
函数原型:
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(); count(key); //统计key的元素个数
示例代码:
1 /*set容器的插入和删除*/ 2 #include<iostream> 3 #include<ctime> 4 #include<set> 5 using namespace std; 6 void printSet(set<int>&s){ 7 for (set<int>::iterator it = s.begin(); it != s.end(); it++) { 8 cout << *it << " "; 9 } 10 cout << endl; 11 } 12 int main() { 13 srand((unsigned)time(NULL)); 14 set<int>s1; 15 for (int i = 0; i < 10; i++) { 16 s1.insert(i); //insert(elem); //在容器中插入元素。 17 } 18 s1.insert(8); 19 printSet(s1); 20 set<int>::iterator pos = s1.find(7); //find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(); 21 if (pos != s1.end()) { 22 cout << "找到元素:" << *pos << endl; 23 } 24 else { 25 cout << "不存在元素:7" << endl; 26 } 27 cout << "元素7的个数是:" << s1.count(7) << endl; //count(key); //统计key的元素个数 28 cout << "元素8的个数是:" << s1.count(8) << endl; //结果为1是因为set中没哟重复的元素 29 cout << "元素666的个数是:" << s1.count(666) << endl; 30 system("pause"); 31 return 0; 32 }
运行结果:
三.更改排序规则
使用方法:
添加自定义类->在类中重载小括号 () -> set的参数列表另加上自定义类类名;
示例代码:
1 /*set容器的排序规则*/ 2 #include<iostream> 3 #include<ctime> 4 #include<set> 5 using namespace std; 6 class MyCompare { 7 public: 8 bool operator()(int x, int y) {//重载操作() 9 return x > y; //降序排列 10 } 11 }; 12 void printSet(const set<int, MyCompare>se) { 13 for (set<int, MyCompare>::iterator it = se.begin(); it != se.end(); it++) { 14 cout << *it << " "; 15 } 16 cout << endl; 17 } 18 int main() { 19 srand((unsigned)time(NULL)); 20 set<int, MyCompare>se; //因为参数列表不能是函数,所以要自定义类 21 for (int i = 0; i < 10; i++) { 22 se.insert(rand()); 23 } 24 printSet(se); 25 system("pause"); 26 return 0; 27 }
运行结果:
四.自定义数据类型指定排序规则
使用方法:
和上面的差不多,只需要改一下set的参数列表和防函数的排序规则
示例代码:
1 /*set容器自定义数据类型指定排序规则*/ 2 #include<iostream> 3 #include<string> 4 #include<set> 5 using namespace std; 6 class Person { //自定义数据类型 7 public: 8 Person(string t_name, int t_age) { 9 this->name = t_name; 10 this->age = t_age; 11 } 12 string name; 13 int age; 14 }; 15 class MyCompare { 16 public: 17 bool operator()(const Person &x, const Person &y) {//重载操作() 18 return x.age > y.age; //降序排列 19 } 20 }; 21 void printSet(const set<Person, MyCompare>se) { 22 for (set<Person, MyCompare>::iterator it = se.begin(); it != se.end(); it++) { 23 cout << (*it).name << " " << (*it).age << endl; 24 } 25 } 26 int main() { 27 set<Person, MyCompare>se; //因为参数列表不能是函数,所以要自定义类 28 Person p1("mzb", 21), p2("cxy", 20), p3("zyf", 19), p4("cxt", 22), p5("tcj", 20); 29 se.insert(p1), se.insert(p2), se.insert(p3), se.insert(p4),se.insert(p5); 30 printSet(se); 31 cout << "p5的年龄和p2的年龄相同,插入失败!" << endl; 32 system("pause"); 33 return 0; 34 }
运行结果:
注意事项:
需要注意的是,上面的 “cxy” 和 “tjc” 由于年龄相同无法插入,当然你会想到我可以通过修改防函数,如果年龄相同我就对姓名进行排序(如下图),但是这是不行的,至于为什么不行,我也不太清楚,源码目前还看不懂;
五.总结
set容器的操作接口相对来说不多,使用起来也比较简单(个人感觉没啥用,还不如直接存入再用sort排序),但是还需要注意以下注意事项:
- 自定义排序规则时的仿函数的类名要放在最后,否则就会报错;
- set容器插入函数返回的是一个 pair对组(第一个参数是迭代器,第二个是布尔类型变量)。
以上是关于set容器的主要内容,如果未能解决你的问题,请参考以下文章
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段