C++系列内容的学习目录 → \rightarrow →C++学习系列内容汇总。
简介: 所有元素都会在插入时自动被排序。
本质: set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset的区别:1. set不允许容器中有重复的元素;
2. multiset允许容器中有重复的元素。
功能描述: 创建set容器以及赋值。
构造:
set<T> st;
//默认构造函数set(const set &st);
//拷贝构造函数赋值:
set& operator=(const set &st);
//重载等号操作符实例如下所示。
#include<iostream> using namespace std; #include<set> //set容器构造和赋值 void printSet(set<int>&s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { set<int>s1; //插入数据:只有insert插入方式 s1.insert(10); s1.insert(40); s1.insert(30); s1.insert(20); s1.insert(30); //遍历容器 //set容器特点:1. 所有元素插入时自动被排序;2. 不允许插入重复值 printSet(s1); //10 20 30 40 //拷贝构造 set<int>s2(s1); printSet(s2); //10 20 30 40 //赋值 set<int>s3; s3 = s2; printSet(s3); //10 20 30 40 } int main() { test01(); system("pause"); return 0; }
10 20 30 40
10 20 30 40
10 20 30 40
总结: 1. set容器插入数据时用insert;
2. set容器插入数据的数据会自动排序。
功能描述: 统计set容器大小以及交换set容器。
函数原型:
size();
//返回容器中元素的数目empty();
//判断容器是否为空swap(st);
//交换两个集合容器实例如下所示。
#include<iostream> using namespace std; #include<set> //set大小和交换 void printSet(set<int>&s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } //大小 void test01() { set<int>s1; //插入数据:只有insert插入方式 s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); printSet(s1); if (s1.empty()) { cout << "s1为空!" << endl; } else { cout << "s1不为空!" << endl; cout << "s1的大小为:" << s1.size() << endl; } } //交换 void test02() { set<int>s1; s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); set<int>s2; s2.insert(100); s2.insert(400); s2.insert(200); s2.insert(300); cout << "交换前:" << endl; printSet(s1); printSet(s2); cout << "交换后:" << endl; s1.swap(s2); printSet(s1); printSet(s2); } int main() { test01(); test02(); system("pause"); return 0; }
10 20 30 40
s1不为空!
s1的大小为:4
交换前:
10 20 30 40
100 200 300 400
交换后:
100 200 300 400
10 20 30 40
总结: set容器没有resize操作。
功能描述: set容器进行插入数据和删除数据。
函数原型:
insert(elem);
//在容器中插入元素clear();
//清除所有元素erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(elem);
//删除容器中值为elem的元素实例如下所示。
#include<iostream> using namespace std; #include<set> //set插入和删除 void printSet(set<int>&s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { set<int>s1; //插入 s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); printSet(s1); //删除 s1.erase(s1.begin()); printSet(s1); //删除的重载版本 s1.erase(30); printSet(s1); //清空 //s1.erase(s1.begin(), s1.end()); s1.clear(); printSet(s1); } int main() { test01(); system("pause"); return 0; }
10 20 30 40
20 30 40
20 40
请按任意键继续. . .
功能描述: 对set容器进行查找数据以及统计数据。
函数原型:
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count(key);
//统计key的元素个数实例如下所示。
#include<iostream> using namespace std; #include<set> //set查找和统计 //查找 void test01() { set<int>s1; //插入数据 s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); //查找 set<int>::iterator pos = s1.find(30); if (pos != s1.end()) { cout << "找到元素:" << *pos << endl; } else { cout << "未找到元素!" << endl; } } //统计 void test02() { set<int>s1; //插入数据 s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(30); //多个元素30,查找时只有一个 s1.insert(30); s1.insert(30); //统计30的个数 int num = s1.count(30); //对于set而言,统计结果要么是0,要么是1 cout << "num = " << num << endl; } int main() { test01(); test02(); system("pause"); return 0; }
找到元素:30
num = 1
总结: 1. 查找find
:返回的是迭代器;
2. 统计count
:对于set,结果为0或者1。
学习目标: 掌握set和multiset的区别。
set和multiset的区别: 1. set不可以插入重复数据,而multiset可以;
2. set插入数据的同时会返回插入结果,表示插入是否成功。
3. multiset不会检测数据,因此可以插入重复数据。
实例如下所示。
#include<iostream> using namespace std; #include<set> //set和multiset区别 void test01() { set<int>s; pair<set<int>::iterator, bool> ret = s.insert(10); if (ret.second) //ret.second代表第二个元素 { cout << "第一次插入成功!" << endl; } else { cout << "第一次插入失败!" << endl; } ret = s.insert(10); if (ret.second) { cout << "第二次插入成功!" << endl; } else { cout << "第二次插入失败!" << endl; } multiset<int>ms; //允许插入重复值 ms.insert(10); ms.insert(10); for(multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
第一次插入成功!
第二次插入失败!
10 10
总结: 如果不允许插入重复数据可以利用set,如果需要插入重复数据利用multiset。
功能描述: 成对出现的数据,利用对组可以返回两个数据。
两种创建方式:
pair<type, type> p ( value1, value2 );
pair<type, type> p = make_pair( value1, value2 );
实例如下所示。
#include<iostream> using namespace std; #include<string> //pair对组的创建 void test01() { //第一种方式 pair<string, int>p1("Tom", 20); cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl; //第二种方式 pair<string, int>p2 = make_pair("Jerry", 30); cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl; } int main() { test01(); system("pause"); return 0; }
姓名:Tom 年龄:20
姓名:Jerry 年龄:30
总结: 两种方式都可以创建对组,记住一种即可。
学习目标: set容器默认排序规则为从小到大,掌握如何改变排序规则。
主要技术点: 利用仿函数,可以改变排序规则。
#include<iostream> using namespace std; #include<set> //set容器的排序 class MyCompare //降序排序规则仿函数 { public: bool operator()(int v1, int v2) { return v1 > v2; } }; void test01() { set<int>s1; s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(50); s1.insert(30); for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { cout << *it << " "; } cout << endl; //指定排序规则为从大到小 set<int, MyCompare>s2; //set容器要在插入数据前指定排序规则,数据插入之后无法修改 s2.insert(10); s2.insert(40); s2.insert(20); s2.insert(50); s2.insert(30); for (set<int>::iterator it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }
10 20 30 40 50
50 40 30 20 10
总结: 1. 利用仿函数可以指定set容器的排序规则;
2. set容器要在插入数据前指定排序规则,数据插入之后无法修改。
#include<iostream> using namespace std; #include<set> #include<string> //set容器的排序 class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } 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 test01() { set<Person, comparePerson>s; //创建Person对象 Person p1("刘备", 24); Person p2("关羽", 28); Person p3("张飞", 25); Person p4("赵云", 21); 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() { test01(); system("pause"); return 0; }
姓名:关羽 年龄:28
姓名:张飞 年龄:25
姓名:刘备 年龄:24
姓名:赵云 年龄:21
总结: 对于自定义数据类型,set必须指定排序规则才可以插入数据。