C++STL 系列(七):set容器详解与示例
·
set 基本概念
set容器特点:
- 所有元素在插入时会自动被排序
- set属于关联式容器,底层结构通常为
二叉树 - set不允许容器中有重复元素
set 构造和赋值
-
set<T> st;// 默认构造函数 -
set(const set &st);// 拷贝构造函数 -
set& operator=(const set &st);// 重载等号操作符 -
示例
// set构造和赋值 /** * set<T> st; // 默认构造函数 * set(const set &st); // 拷贝构造函数 * set& operator=(const set &st); // 重载等号操作符 * * set容器特点: * 1. 所有元素在插入时会自动被排序 * 2. set属于关联式容器,底层结构通常为二叉树 * 3. set不允许容器中有重复元素 */ #include <iostream> #include <set> using namespace std; void print_set(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test0() { // 1. 默认构造 set<int> s1; // set容器只能通过insert插入元素 // insert s1.insert(10); s1.insert(20); s1.insert(30); // 插入重复元素,不会插入成功 s1.insert(30); s1.insert(40); cout << "s1 = "; print_set(s1); // 2. 拷贝构造 set<int> s2(s1); cout << "s2 = "; print_set(s2); // 3. 赋值 set<int> s3; s3 = s1; cout << "s3 = "; print_set(s3); } int main() { test0(); return 0; }
set 大小和交换
-
size();// 返回容器中元素的数目 -
empty();// 判断容器是否为空 -
swap(set);// 交换两个集合容器 -
示例
// set大小和交换 /** * size(); // 返回容器中元素的数目 * empty(); // 判断容器是否为空 * swap(set); // 交换两个集合容器 */ #include <iostream> #include <set> using namespace std; void print_set(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test0() { set<int> s1; // 1. empty if (s1.empty()) { cout << "s1 is empty" << endl; } else { cout << "s1 is not empty" << endl; } // insert s1.insert(10); s1.insert(20); s1.insert(30); s1.insert(40); // 2. size cout << "the size of s1 is: " << s1.size() << endl; cout << "s1 = "; print_set(s1); // 3. swap set<int> s2; s2.insert(100); s2.insert(200); s2.insert(300); s2.insert(400); cout << "s2 = "; print_set(s2); s1.swap(s2); cout << "after swap: " << endl; cout << "s1 = "; print_set(s1); cout << "s2 = "; print_set(s2); } int main() { test0(); return 0; }
set 插入和删除
-
insert(elem);// 在容器中插入元素 -
erase(pos);// 删除pos迭代器所指的元素,返回下一个元素的迭代器 -
erase(beg, end);// 删除区间[beg, end)的所有元素,返回下一个元素的迭代器 -
erase(elem);// 删除容器中值为elem的元素 -
clear();// 清除所有元素 -
示例
// set插入和删除 /** * insert(elem); // 在容器中插入元素 * erase(pos); // 删除pos迭代器所指的元素,返回下一个元素的迭代器 * erase(beg, end); // 删除区间[beg, end)的所有元素,返回下一个元素的迭代器 * erase(elem); // 删除容器中值为elem的元素 * clear(); // 清除所有元素 */ #include <iostream> #include <set> using namespace std; void print_set(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test0() { set<int> s1; // 1. insert s1.insert(10); s1.insert(20); s1.insert(30); s1.insert(40); s1.insert(50); cout << "s1 = "; print_set(s1); // 2. erase(pos) s1.erase(s1.begin()); cout << "s1 = "; print_set(s1); // 3. erase(beg, end) s1.erase(--s1.end(), s1.end()); cout << "s1 = "; print_set(s1); // 4. erase(elem) s1.erase(20); cout << "s1 = "; print_set(s1); // 5. clear s1.clear(); cout << "s1 = "; print_set(s1); } int main() { test0(); return 0; }
set 查找和统计
-
find(key);// 查找key是否存在,若存在返回该键的元素的迭代器,若不存在返回set.end() -
count(key);// 统计key的元素个数 -
对于set容器,count(key)的结果只能是0或1,因为set不允许插入重复元素。
-
示例
// set查找和统计 /** * find(key); // 查找key是否存在,若存在返回该键的元素的迭代器,若不存在返回set.end() * count(key); // 统计key的元素个数 * * 对于set容器,count(key)的结果只能是0或1,因为set不允许插入重复元素。 */ #include <iostream> #include <set> using namespace std; void test0() { set<int> s1; s1.insert(10); s1.insert(20); s1.insert(30); s1.insert(40); s1.insert(50); // 1. find set<int>::iterator pos = s1.find(30); if (pos != s1.end()) { cout << "find the element: " << *pos << endl; } else { cout << "not find the element" << endl; } set<int>::iterator pos2 = s1.find(300); if (pos2 != s1.end()) { cout << "find the element: " << *pos2 << endl; } else { cout << "not find the element" << endl; } // 2. count int num = s1.count(30); cout << "the number of 30 is: " << num << endl; } int main() { test0(); return 0; }
set 和multiset的区别
-
set不允许容器中有重复元素- set插入数据的同时会返回插入结果,表示插入是否成功
pair<set<T>::iterator, bool> ret = st.insert(elem);- pair用于表示一对值,在这里first表示插入的元素的迭代器,second表示插入是否成功
-
multiset允许容器中有重复元素- multiset不会检测数据是否重复,因此可以插入重复数据
-
示例
// set和multiset的区别 /** * set不允许容器中有重复元素 * multiset允许容器中有重复元素 * * set插入数据的同时会返回插入结果,表示插入是否成功 * pair<set<T>::iterator, bool> ret = st.insert(elem); * pair用于表示一对值,在这里first表示插入的元素的迭代器,second表示插入是否成功 * * multiset不会检测数据是否重复,因此可以插入重复数据 * multiset<T> mst; * mst.insert(elem); */ #include <iostream> #include <set> using namespace std; void test0() { // set set<int> s1; s1.insert(10); s1.insert(20); pair<set<int>::iterator, bool> ret = s1.insert(20); if (ret.second) { cout << "insert success" << endl; } else { cout << "insert failed" << endl; } // print set for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { cout << *it << " "; } cout << endl; // multiset multiset<int> ms1; ms1.insert(10); ms1.insert(20); ms1.insert(20); ms1.insert(20); // print multiset for (multiset<int>::iterator it = ms1.begin(); it != ms1.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test0(); return 0; }
set 中pair的创建
pair用于存储一对数据,通过first和second来分别访问
-
pair<T1, T2> p(value1, value2);// 方式一:通过构造函数创建pair -
pair<T1, T2> p = make_pair(value1, value2);// 方式二:通过make_pair创建pair -
pair.first// 获取第一个元素 -
pair.second// 获取第二个元素 -
示例
// pair的创建 /** * pair<T1, T2> p(value1, value2); // 方式一:通过构造函数创建pair * pair<T1, T2> p = make_pair(value1, value2); // 方式二:通过make_pair创建pair * * pair.first // 获取第一个元素 * pair.second // 获取第二个元素 */ #include <iostream> #include <utility> using namespace std; void test0() { // 1.构造函数创建 pair<string, int> p1("GG bond", 18); cout << "p1.first = " << p1.first << ", p1.second = " << p1.second << endl; // 2. make_pair创建 pair<string, int> p2 = make_pair("Xi Yangyang", 88); cout << "p2.first = " << p2.first << ", p2.second = " << p2.second << endl; } int main() { test0(); return 0; }
set 指定排序规则
-
内置类型
- 和sort函数一样,set已经包含了对内置类型的比较函数(这里是仿函数),实现升序效果
- 可以提供仿函数来实现降序效果
-
仿函数语法示例
class my_compare { public: bool operator()(int v1, int v2) const { return v1 > v2; // 降序 } }; set<int, my_compare> st; // 对内置数据类型指定排序规则 -
示例
// set指定排序规则 - 内置类型 /** * set<T, Compare> st; // 创建set容器时指定排序规则 * * 仿函数示例: * class my_compare * { * public: * bool operator()(int v1, int v2) const * { * return v1 > v2; // 降序 * } * }; * * set<int, my_compare> st; // 对内置数据类型指定排序规则 */ #include <iostream> #include <set> using namespace std; // 仿函数 class my_compare { public: bool operator()(int v1, int v2) const { return v1 > v2; // 降序 } }; void print_set(const set<int, my_compare>& s) { for (set<int, my_compare>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test0() { // 在创建时就要指定排序规则 set<int, my_compare> s1; s1.insert(10); s1.insert(20); s1.insert(30); s1.insert(40); s1.insert(50); cout << "s1 = "; print_set(s1); } int main() { test0(); return 0; }
-
自定义类型
- 对于自定义数据类型,set必须指定排序规则才可以插入数据
- 如果不提供排序规则,编译器会报错,因为无法比较自定义类型
-
仿函数语法示例
class compare_person { public: bool operator()(const person &p1, const person &p2) const { return p1.m_age > p2.m_age; // 按年龄降序 } }; set<person, compare_person> st; // 对自定义数据类型指定排序规则 -
示例
// set指定排序规则 - 自定义类型 /** * 对于自定义数据类型,set必须指定排序规则才可以插入数据 * 如果不提供排序规则,编译器会报错,因为无法比较自定义类型 * * 自定义排序规则示例: * class compare_person * { * public: * bool operator()(const person &p1, const person &p2) const * { * return p1.m_age > p2.m_age; // 按年龄降序 * } * }; * * set<person, compare_person> st; // 对自定义数据类型指定排序规则 */ #include <iostream> #include <set> using namespace std; // 自定义类型 class person { public: person(string name, int age) : name_(name), age_(age) {} string name_; int age_; }; // 仿函数 class compare_person { public: bool operator()(const person &p1, const person &p2) const { return p1.age_ > p2.age_; // 年龄降序 } }; void test0() { set<person, compare_person> s1; s1.insert(person("GG bond", 12)); s1.insert(person("Mask", 50)); s1.insert(person("Lei Jun", 45)); // print for (set<person, compare_person>::const_iterator it = s1.begin(); it != s1.end(); it++) { cout << (*it).name_ << " " << (*it).age_ << endl; } } int main() { test0(); return 0; }
更多推荐

所有评论(0)