关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

STL-set/multiset集合容器

发布时间:2023-06-30 16:00:46

特点:

  • 所有元素在插入时会被自动排序

本质:

  • set/multiset属于关联式容器,底层结构使用二叉树实现

set和multiset区别:

  • set不允许容器中有重复的元素
  • multiset允许容器中有重复元素

set构造和赋值

构造:

  • setst;//默认构造函数
  • set(const set& st);//拷贝构造函数

赋值:

  • set& operator=(const set& st);//重载等号运算符

set插入数据只有.insert(elem)方法

setl; //准备数据 l.insert(3); l.insert(2); l.insert(4); l.insert(5); l.insert(1); //set容器不允许插入重复值,虽然没有报错,但也插不成功 l.insert(1); for (set::iterator it = l.begin(); it != l.end(); it++) {  cout << *it << " ";//1 2 3 4 5 }

   


set大小和交换

  • .size();//返回容器中元素个数
  • .empty();//判断容器是否为空
  • .swap(st);//交换两个集合容器

没有.resize()方法:

  • 剩余部分用0填充,与set不允许重复这一特性矛盾
#include#include#includeusing namespace std; void PrintSet(const set& st) {  //可以不用只读迭代器  for (set::const_iterator it = st.begin(); it != st.end(); it++)  {  cout << *it << " ";  }  cout << endl << st.size() << " " << st.empty() << endl; } int main() {  setst;  st.insert(2);  st.insert(1);  st.insert(3);  st.insert(5);  st.insert(4);  PrintSet(st);  setst1;  for (int i = 0; i < 10; i++)  {  st1.insert(i);  }  PrintSet(st1);  st.swap(st1);  PrintSet(st);  PrintSet(st1);  return 0; }

   


set插入和删除

  • .insert(elem);//在容器中插入元素
  • .clear();//清除所有元素
  • .erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器
  • .erase(beg, end);//删除[beg,end)区间内的元素,返回下一个元素的迭代器
  • .erase(elem);//删除容器中值为elem的元素
    • 类似于list容器中的.remove(elem);方法

set查找和统计

  • .find(key);//查找key是否存在,若存在,返回该元素的迭代器,若不存在,返回.end()
  • .count(key);//统计key的个数
    • 由于set不允许插入重复值,因此结果只有0或1
setst; st.insert(2); st.insert(1); st.insert(3); st.insert(5); st.insert(4); //查找 //由于find返回值是一个迭代器,所以也需要创建一个迭代器来接收它 set::iterator pos = st.find(4); if (pos != st.end())  cout << "找到了" << *pos << endl; else  cout << "没找到" << endl; //统计 cout << st.count(3) << endl;

   


set和multiset区别

  • set不可以插入重复数据,multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以插入重复数据
setst; //set容器插入的返回值是pair,有两个参数:迭代器和布尔 pair<set::iterator,bool>ret= st.insert(4); if (ret.second)  cout << "插入成功" << endl;//√ else  cout << "插入失败" << endl; ret = st.insert(4); if (ret.second)  cout << "插入成功" << endl; else  cout << "插入失败" << endl;//√ //multiset插入的返回值是一个迭代器,不会进行判断,插多少是多少

   


pair对组创建

成对出现的数据,利用对组可以返回两个数据

两种创建方式:

  • pairp(value1, value2);
  • pairp = make_pair(value1, value2);
//创建pair pairp1("张三", 10); pairp2 = make_pair("李四", 20); //通过.first和.second访问 cout << p1.first << p1.second << endl; p2.first = p1.first; cout << p2.first << p2.second << endl;

   


set容器指定排序规则

利用仿函数,可以改变排序规则

仿函数就是重载()运算符


内置数据类型自定义排序

函数名后需要加const修饰

  • 在仿函数中,对于传入的参数进行操作时,如果没有加上const,那么默认这个参数是可以被修改的。
  • 而在set容器中,元素是不允许修改的,所以如果仿函数中没有加上const,会与set容器的实现矛盾,导致编译错误。
  • 而加上const则表示这个参数是只读的,不会对其进行修改,就能避免这个错误。
#include#include#includeusing namespace std; //set容器排序 class MyCompare { public:  //不加const会报错  bool operator()(int v1, int v2)const  {  return v1 > v2;  } }; int main() {  sets1;  s1.insert(10);  s1.insert(30);  s1.insert(20);  //默认规则为从小到大  for (set::iterator it = s1.begin(); it != s1.end(); it++)  {  cout << *it << " ";  }  cout << endl;  //指定排序规则为从大到小  sets2;  s2.insert(10);  s2.insert(30);  s2.insert(20);  for (set::iterator it = s2.begin(); it != s2.end(); it++)  {  cout << *it << " ";  }  return 0; }

   


自定义数据类型排序

对于自定义数据类型,都会指定排序规则,否则编译器不知道该按照什么排序

#include#include#includeusing namespace std; class Person { public:  Person(string name, int age)  {  this->m_name = name;  this->m_age = age;  }  string m_name;  int m_age; }; //set容器排序 class ComparePerson { public:  //不加const会报错  bool operator()(const Person& p1, const Person& p2)const  {  return p1.m_age > p2.m_age;  } }; int main() {  sets;  Person p1("A", 10);  Person p2("B", 30);  Person p3("C", 20);  Person p4("D", 40);  Person p5("E", 40);  s.insert(p1);  s.insert(p2);  s.insert(p3);  s.insert(p4);  s.insert(p5);//由于p4,p4的年龄相同,p5会插入失败  for (set::iterator it = s.begin(); it != s.end(); it++)  {  cout << (*it).m_name << " " << (*it).m_age << endl;  }  return 0; }

/template/Home/leiyu/PC/Static