黑马c++ STL部分 笔记(8) set/ multiset 容器

简介: 黑马c++ STL部分 笔记(8) set/ multiset 容器

简介

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

本质

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

set和multiset区别

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

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


1.set构造和赋值

// set构造和赋值
/*
构造:
set<T> st; //默认构造函数:
set(const set &st); //拷贝构造函数
赋值:
set& operator=(const set &st); //重载等号操作符
*/
#include <bits/stdc++.h>
using namespace std;
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); // 插入数据只有insert方式
  s1.insert(30);
  s1.insert(40);
  s1.insert(20);
  s1.insert(30);
  // set里的元素自动被排序,不允许插入重复的值
  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();
}
/*
总结:
set容器插入数据时用insert
set容器插入数据的数据会自动排序
*/


2. set大小和交换

// set大小和交换
/*不支持resize
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
*/
#include <bits/stdc++.h>
using namespace std;
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(30);
  s1.insert(40);
  s1.insert(20);
  s1.insert(30);
 
  printset(s1); // 10 20 30 40
  if (s1.empty())
  {
    cout << "s1为空" << endl;
  }
  else
  {
    cout << "s1为不空" << endl;
    cout << s1.size() << endl; // 4
  }
  set<int> s2;
  s2.insert(10);
  printset(s2); // 10
  s1.swap(s2);
  printset(s1); // 10
  printset(s2); // 10 20 30 40
}
int main()
{
  test01();
}
/*
总结:
统计大小 — size
判断是否为空 — empty
交换容器 — swap
*/


3.set插入和删除

// set插入和删除
/*
insert(elem); //在容器中插入元素。
clear(); //清除所有元素
erase(pos); //删除pos'迭代器'所指的元素,返回下一个元素的迭代器。
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem); //删除容器中'值'为elem的元素。(类似remove)
*/
#include <bits/stdc++.h>
using namespace std;
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(30);
  s1.insert(10);
  s1.insert(40);
  s1.insert(20);
  s1.insert(30);
  printset(s1); // 10 20 30 40
  // 删除迭代器位置
  s1.erase(s1.begin());
  printset(s1); // 20 30 40
  // 删除元素
  s1.erase(40);
  printset(s1); // 20 30
  // 清空
  s1.clear();
  printset(s1);
}
int main()
{
  test01();
}
/*
总结:
插入 — insert
删除 — erase
清空 — clear
*/


4.set查找和统计

// set查找和统计
/*
find(key); //查找key是否存在,若存在,返回该键的元素的'迭代器';若不存在,返回'set.end()';
count(key); //统计key的'元素'个数  set中返回0/1 multiset为0/>0的值
*/
#include <bits/stdc++.h>
using namespace std;
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(30);
  s1.insert(10);
  s1.insert(40);
  s1.insert(20);
  s1.insert(30);
  printset(s1); // 10 20 30 40
  // 查找
  set<int>::iterator pos = s1.find(40);
  if (pos != s1.end())
  {
    cout << "找到元素:" << *pos << endl; // 找到元素:40
  }
  else
  {
    cout << "未找到元素:" << endl;
  }
  // 统计
  int num = s1.count(30); // 统计30的个数
  cout << num << endl;    // 1
}
int main()
{
  test01();
}
/*
总结:
查找 — find (返回的是迭代器)
统计 — count (对于set,结果为0或者1)
*/


5.set和multiset区别

// set和multiset区别
/*
区别:
set不可以插入重复数据,而multiset可以
set插入数据的同时会返回插入结果,表示插入是否成功
multiset不会检测数据,因此可以插入重复数据
*/
#include <bits/stdc++.h>
using namespace std;
void test01()
{
  set<int> s;
  // set插入
  pair<set<int>::iterator, bool> ret = s.insert(10);
  if (ret.second)
  {
    cout << "第一次插入成功" << endl; // √
  }
  else
  {
    cout << "第一次插入失败" << endl; // ×
  }
  // set重复插入
  ret = s.insert(10);
  if (ret.second)
  {
    cout << "第二次插入成功" << endl; // ×
  }
  else
  {
    cout << "第二次插入失败" << endl; // √
  }
  multiset<int> s2;
  // multiset插入
  s2.insert(10);
  // multiset重复插入
  s2.insert(10);
  for (multiset<int>::iterator it = s2.begin(); it != s2.end(); it++)
  {
    cout << *it << " "; // 10 10
  }
}
int main()
{
  test01();
}
/*
总结:
如果不允许插入重复数据可以利用set
如果需要插入重复数据利用multiset
*/


6. pair对组创建

// pair对组创建
/*
两种创建方式:
pair<type, type> p ( value1, value2 );
pair<type, type> p = make_pair( value1, value2 );
*/
#include <bits/stdc++.h>
using namespace std;
void test01()
{
  pair<string, int> p("Tom", 20);
  cout << p.first << " " << p.second << endl; // Tom 20
  pair<string, int> p2 = make_pair("Jerry", 15);
  cout << p2.first << " " << p2.second << endl; // Jerry 15
}
int main()
{
  test01();
}
/*
总结:
两种方式都可以创建对组,记住一种即可
*/


7.1  set容器排序

示例一 set存放内置数据类型

//  set容器排序
/*
学习目标:
set容器默认排序规则为从小到大,掌握如何改变排序规则
主要技术点:
利用仿函数,可以改变排序规则
*/
// 示例一 set存放内置数据类型
#include <bits/stdc++.h>
using namespace std;
class cmp // 仿函数(类)
{
public:
  bool operator()(int v1, int v2)
  {
    return v1 > v2;
  }
};
void test01()
{
  // 升序
  set<int> s1;
  s1.insert(10);
  s1.insert(30);
  s1.insert(20);
  s1.insert(50);
  s1.insert(40);
  for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
  {
    cout << *it << " "; // 10 20 30 40 50
  }
  cout << endl;
  // 降序,在创建容器时就指定排序规则
  set<int, cmp> s2;
  s2.insert(10);
  s2.insert(30);
  s2.insert(20);
  s2.insert(50);
  s2.insert(40);
  for (set<int, cmp>::iterator it = s2.begin(); it != s2.end(); it++)
  {
    cout << *it << " "; // 50 40 30 20 10
  }
  cout << endl;
}
int main()
{
  test01();
}
/*
总结:
对于自定义数据类型,set必须指定排序规则才可以插入数据
*/


7.2  set容器排序

示例二 set存放自定义数据类型

//  set容器排序
// 示例二 set存放自定义数据类型
#include <bits/stdc++.h>
using namespace std;
 
class person
{
public:
  person(string name, int age)
  {
    this->name = name;
    this->age = age;
  }
  string name;
  int age;
};
class cmp
{
public:
  bool operator()(person p1, person p2)
  {
    // 按年龄降序
    return p1.age > p2.age;
  }
};
void test01()
{
  /// 自定义的类型 都会指定排序类型
  set<person, cmp> s;
  person s1("刘备", 24);
  person s2("关羽", 28);
  person s3("张飞", 25);
  person s4("赵云", 21);
  s.insert(s1);
  s.insert(s2);
  s.insert(s3);
  s.insert(s4);
  for (set<person, cmp>::iterator it = s.begin(); it != s.end(); it++)
  {
    cout << (*it).name << " " << (*it).age;
    /*
   关羽 28
   张飞 25
   刘备 24
   赵云 21
   */
    cout << endl;
  }
}
int main()
{
  test01();
}
/*
总结:
对于自定义数据类型,set必须指定排序规则才可以插入数据
*/


相关文章
|
1月前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
94 10
|
1月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
69 5
|
1月前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
52 1
|
1月前
|
算法 安全 Linux
【C++STL简介】——我与C++的不解之缘(八)
【C++STL简介】——我与C++的不解之缘(八)
|
1月前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
22 0
|
6天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
28 2
|
16天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
12天前
|
关系型数据库 MySQL API
|
5天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。
|
6天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?