STL_set/multiset
简介:本文主要介绍STL中的,set与multiset的使用,只需要把本文的代码自己敲完便可学会。
set容器的基本概念
注意:set容器没有push_back, pop_back这两种插入接口,只能用insert函数进行插入
如果向set容器种插入相同元素,不会报错,但是打印的时候会自动滤去多余的元素,一个元素只能有一个,而且打印结果事是排好序了的。
Note:the set container has no push_back and pop_back these two kinds of insertion interface, can only use the insert function to insert.
if the same element is inserted into the set container, no error will be reported, but the redundant elements will be automatically filtered out when printing. There can only be one element, and the printing results are in good order.
set的构造方法
学习代码:
#include<iostream> #include<set> using namespace std; /*Construction and assignment of set container*/ // 遍历set的函数 void PrintSet(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 data only the way to insert data // 通过insert方法给set插入元素 s1.insert(10); s1.insert(0); s1.insert(30); s1.insert(30); s1.insert(20); // Traverse container // 遍历容器 cout << "s1: " << endl; // Automaticallu order and remove duplicate elements // 0 10 20 30 PrintSet(s1); cout << endl; // Copy constructor // 拷贝函数来构造 set<int>s2(s1); cout << "s2: " << endl; // 0 10 20 30 PrintSet(s2); cout << endl; // Assgin // 也是拷贝构造函数,用=运算符实现 set<int>s3; s3 = s1; cout << "s3: " << endl; // 0 10 20 30 PrintSet(s3); cout << endl; } int main() { test01(); return 0; }
运行结果:
set大小和交换
学习代码:
#include<iostream> #include<set> using namespace std; /*Size container, size and swap*/ void PrintSet(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; // Data insert // 插入数据 s1.insert(10); s1.insert(20); s1.insert(30); s1.insert(40); // Print cout << "s1: "; PrintSet(s1); cout << endl; // Judge empty if (s1.empty()) { cout << "s1为空" << endl; } else { cout << "s1不为空" << endl << "s1的大小为:" << s1.size() << endl; } // Swap set<int>s2; s2.insert(12); s2.insert(80); s2.insert(132); s2.insert(567); cout << "s1:" << endl; PrintSet(s1); cout << endl; cout << "-----------------\n" << endl; cout << "交换操作\n" << endl; cout << "交换前:" << endl; cout << "s1:"; PrintSet(s1); cout << endl; cout << "s2:"; PrintSet(s2); cout << endl; cout << "交换后:" << endl; // 交换set容器中的数据 s1.swap(s2); cout << "s1:"; PrintSet(s1); cout << endl; cout << "s2:"; PrintSet(s2); cout << endl; } int main() { test01(); return 0; }
运行结果:
set插入和删除
注意:set内部的底层原理是树状结构,所以和链表一样,迭代器都不支持像“+ n”, “- n”之类的直接的更改位置,原因和链表list相似,要改的话也只能用++或–。
Note:the underlying principle of set is tree structure, so like linked lists, iterators do not support direct location changes such as “+ n”, “- n”.The reason is similar to linked list to linked list, so you can only use ++ or --;
学习代码:
#include<iostream> #include<set> using namespace std; /*Set container, Insertion and deletion*/ void PrintSet(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; // Data insert // 插入数据 s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(4); // Traverse // 遍历 cout << "s1: " << endl; // 4 10 20 30 PrintSet(s1); cout << endl; // Deletion // 删除第一个元素 s1.erase(s1.begin()); // Find the location of deletion through iterator // Operators other than ++ and -- operator are not supported // 10 20 30 cout << "s1: " << endl; PrintSet(s1); cout << endl; s1.erase(20); // delete by value 按值删除元素 // 10 30 cout << "s1: " << endl; PrintSet(s1); cout << endl; // clear s1.erase(s1.begin(), s1.end()); // Through iterator 删除一个区间 cout << "s1: " << endl; PrintSet(s1); cout << endl; // The two ways are the same s1.clear(); cout << "s1: " << endl; PrintSet(s1); cout << endl; } int main() { test01(); return 0; }
运行结果:
set查找和统计
注意:由于set函数具有元素不重复的特点,所以count函数的返回值要么是0,要么是1,multiset允许重复值,所以返回值可能不一样,利用这个性质我们也可以通过count函数来判断该元素是否存在于这个容器中。
end()迭代器表示的是最后一个元素的下一个位置,不是最后一个元素的位置。
Note:because the set function has the feature of non repeating elements, the return value of the return value of the count function is either 0 or 1. multiset allows repeating values, so the return value may be different. Using this property,we can also use the count function to determine whether the element exists in this container.
The end() iterator represents the next position of the last element, not the position of the last element,
运行结果:
set和multiset区别
注意:这里引入的对组pair概念后面会简单的讲解,这里使用对组pair的目的是检验insert函数是否插入成功,验证set不能存放两个相同的元素。
multiset相对set除了可以插入重复的值以外其他的都是相似的。
Note: the concept of pair introduced here will be explained briefly later, The purpose of using pair here is to check whether the insert function is inserted successfully and verify that set cannot store two identical elements.
Multiset is similar to set except that it can insert duplicate values,
学习代码:
#include<iostream> #include<set> using namespace std; /*The different between set and multiset*/ void PrintSet(const set<int>& s) { for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void PrintSet(const multiset<int>& s) { for (multiset<int>::const_iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { set<int>s1; // Data insert pair<set<int>::iterator, bool> ret = s1.insert(10); // multiset貌似不能够这样做 if (ret.second) { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } cout << "当前存放元素" << endl; cout << "s1: "; PrintSet(s1); cout << endl; ret = s1.insert(10); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } cout << "当前存放元素" << endl; cout << "s1: "; PrintSet(s1); cout << endl; cout << "------------------" << endl; multiset<int>ms; // Insert repeat element ms.insert(20); ms.insert(20); cout << "ms: " << endl; PrintSet(ms); cout << endl; } int main() { test01(); cout << endl; return 0; }
运行结果:
set容器排序
注意:定义的这个类就是这个仿函数,迭代器的类型要与定义的时候的类型一样。
set容器的顺序在定义的时候就已经拍好了,不能再更改了
这个类里面的函数定义的方法记住就好了,以后会详细讲解
Note:the defined “class” is the imitation function, and the type of iterator should be the same as the defined type.
The sequence of the set container has been arranged at the time of definition and can’t be changed any more.
Just remember the method of function definition in this class,which will be explained in detail later.
运行结果:
#include<iostream> #include<set> using namespace std; /*set container sort*/ class MyCompare // This class MyCmp is an imitation function { public: bool operator()(int v1, int v2) const // 后面一定要加这个const表示这个函数是常函数,不然vs2019会报错 { return v1 > v2; } }; void PrintSet(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; // Data insert s1.insert(10); s1.insert(30); s1.insert(40); s1.insert(50); s1.insert(20); cout << "s1: " << endl; // 10 20 30 40 50 PrintSet(s1); // The default rule is from small to large cout << endl; // Specify rules from small to large // 自定义排序值从大到小 set<int, MyCompare>s2; s2.insert(10); s2.insert(30); s2.insert(40); s2.insert(50); s2.insert(20); cout << "s2: " << endl; // 50 40 30 20 10 for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) // Different definitions have different iterators { cout << *it << " "; } cout << endl; } int main() { test01(); cout << endl; return 0; }
运行结果: