当前位置: 首页 > news >正文

c++:SLT容器之set、map详解

在这里插入图片描述

SLT容器之set、map详解

  • 一、set容器
    • (一)函数分析
      • 1、set的构造函数
      • 2、set的插入
      • 3、set的查找
      • 4、set的删除
      • 5、set和multiset的区别
    • (二)set容器模拟实现
  • 二、map容器
    • (一)函数分析
      • 1、pair类型介绍
      • 2、map的构造函数
      • 3、map的插入
      • 4、map的查找
      • 4、map的删除
      • 5、map的修改(value)
      • 7、map和multimap的区别
      • 8、结构化绑定遍历

序列式容器和关联式容器

  • 序列式容器:相互的两个值之间没有紧密的联系(线性结构),可以交换任意两个值。如string、vector、list、deque、array、forward_list
  • 关联式容器:相互的两个位置有紧密的关联关系(通常为非线性结构),不能不是任意的两个值都能交换。如map/set,unordered_map/unordered_set系列。

一、set容器

set容器显然也是类模板,底层是一个平衡二叉搜索树

  • 第一个参数是key值,作为插入标准,不可被修改
  • 第二个参数是一个仿函数,默认参数的是一个less类,因此默认是从小到大排序。
  • 第三参数是空间配置器。
    在这里插入图片描述

(一)函数分析

1、set的构造函数

一般来说,最常用的三种构造方式就是下面三种

  • 直接构造,选择后续插入值
  • 使用迭代器区间构造,它方便我们将其他的容器里的值引入进来
  • 使用初始化列表构造,同样便捷。
    在这里插入图片描述
void test01() {set<int> s1;set<int> s2({ 2,3,43,54,65,32,41,5,34 });vector<int> v({ 23,43,65,76,24,48 });set<int, greater<int>> s3(v.begin(), v.end());for (auto x : s1) {cout << x << " ";}cout << endl;for (auto x : s2) {cout << x << " ";}cout << endl;for (auto x : s3) {cout << x << " ";}cout << endl;
}

在这里插入图片描述

2、set的插入

和上面的构造相似,插入对应三种方式。
在这里插入图片描述

void test02() {set<int> s1;s1.insert(3);for (auto e : s1){cout << e << " ";}cout << endl;s1.insert({ 2,8,3,9 });for (auto e : s1){cout << e << " ";}vector<int> v({ 23,43,65,76,24,48 });s1.insert(v.begin(), v.end());cout << endl;for (auto e : s1){cout << e << " ";}cout << endl;
}

在这里插入图片描述

3、set的查找

在这里查找常用的有下面三种方式,其中第二种统计出现的次数,返回值为0(不存在)或者1(存在),加入这个接口是为了和multiset到达同时兼容。
在这里插入图片描述

void test03() {std::set<int> myset = { 10,20,35 ,40 ,50 ,65 ,70 ,80 ,90 };for (auto e : myset){cout << e << " ";}cout << endl;set<int>::iterator it = myset.find(10);cout << *it << endl;int n = myset.count(20);cout << n << endl;// 实现查找到的[itlow,itup)包含[30, 60]区间]// 返回 >= 30auto itlow = myset.lower_bound(30);// 返回 > 60auto itup = myset.upper_bound(60);for (auto x = itlow; x != itup; x++) cout << *x << " ";
}

在这里插入图片描述

4、set的删除

删除主要是单个值的删除和迭代器区间的删除。
在这里插入图片描述

void test04() {std::set<int> myset = { 10,20,35 ,40 ,50 ,65 ,70 ,80 ,90 };for (auto e : myset){cout << e << " ";}cout << endl;// 实现查找到的[itlow,itup)包含[30, 60]区间]// 返回 >= 30auto itlow = myset.lower_bound(30);// 返回 > 60auto itup = myset.upper_bound(60);// 删除这段区间的值myset.erase(itlow, itup);for (auto e : myset){cout << e << " ";}cout << endl;
}

在这里插入图片描述

5、set和multiset的区别

我们通过下面的代码可以看出区别。

void test05() {multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };auto it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;
}

在这里插入图片描述
multiset和set的使⽤基本完全类似,区别在于multiset⽀持值冗余,insert/find/count/erase都围绕着⽀持值冗余有所差异

void test06() {multiset<int> s = { 4,2,7,2,4,8,4,5,4,9,4 };for (auto e : s){cout << e << " ";}cout << endl;//相比set不同的是,x可能会存在多个,find查找中序的第一个auto pos = s.find(4);while (pos != s.end() && *pos == 4){cout << *pos << " ";++pos;}cout << endl;// 相比set不同的是,count会返回x的实际个数cout << s.count(4) << endl;//// 相比set不同的是,erase给值时会删除所有的xs.erase(4);for (auto e : s){cout << e << " ";}cout << endl;
}

在这里插入图片描述

(二)set容器模拟实现

二、map容器

和上面的set唯一的区别就是map是key_value结构,因此就多了一个模板参数。
在这里插入图片描述

(一)函数分析

1、pair类型介绍

pair是一个类模板,可以将两种类型绑定起来,达到一一对应的效果。

typedef pair<const Key, T> value_type;
template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}template<class U, class V>pair(const pair<U, V>& pr) : first(pr.first), second(pr.second){}
};
template <class T1, class T2>
inline pair<T1, T2> make_pair(T1 x, T2 y)
{return (pair<T1, T2>(x, y));
}
void test07() {pair<string, string> kv1("first", "第一个");pair<string, string> kv2 = make_pair("sort", "排序");cout << kv1.first << " " << kv1.second << endl;cout << kv2.first << " " << kv2.second << endl;
}

在这里插入图片描述

2、map的构造函数

通常使用下面三种方式实现构造初始化

  • 直接构造,选择后续插入值
  • 使用迭代器区间构造,它方便我们将其他的容器里的值引入进来
  • 使用初始化列表构造,同样便捷。
    在这里插入图片描述
void test08() {// initializer_list构造及迭代遍历cout << "initializer_list构造及迭代遍历" << endl;map<string, string> dict1 = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };auto it = dict1.begin();while (it != dict1.end()){cout << it->first << ":" << it->second << endl;++it;}//迭代器区间构造cout << endl;cout << "迭代器区间构造" << endl;vector<pair<string,string>> v = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };map<string, string> dict2(v.begin(), v.end());auto it2 = dict2.begin();while (it2 != dict2.end()){cout << it2->first << ":" << it2->second << endl;++it2;}cout << endl;
}

在这里插入图片描述

3、map的插入

插入主要也是三种方式,单值插入、迭代器区间插入以及initializer_list插入
在这里插入图片描述

void test10() {map<string, string> dict = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };pair<string, string> kv1("first", "第一个");dict.insert(kv1);dict.insert(pair<string, string>("second", "第二个"));dict.insert(make_pair("sort", "排序"));dict.insert({ "auto", "自动的" });for (const auto& e : dict){cout << e.first << ":" << e.second << endl;}cout << endl;
}

在这里插入图片描述

4、map的查找

// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find (const key_type& k);
// 查找k,返回k的个数
size_type count (const key_type& k) const;
// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);
// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;

4、map的删除

// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除k,k存在返回0,存在返回1
size_type erase (const key_type& k);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);

5、map的修改(value)

map支持修改value数据

  • 迭代器,迭代器返回其value进行修改
  • operator[],不仅仅支持修改,还支持插入数据和查找数据
    operator[]
    1、如果k不在map中,insert会插⼊k和mapped_type默认值,同时[]返回结点中存储
    mapped_type值的引⽤,那么我们可以通过引⽤修改返映射值。所以[]具备了插⼊+修改功能
    2、如果k在map中,insert会插⼊失败,但是insert返回pair对象的first是指向key结点的
    迭代器,返回值同时[]返回结点中存储mapped_type值的引⽤,所以[]具备了查找+修改的功能
key_type -> The first template parameter (Key)
mapped_type -> The second template parameter (T)
value_type -> pair<const key_type,mapped_type>mapped_type& operator[] (const key_type& k)
{pair<iterator, bool> ret = insert({ k, mapped_type() });
iterator it = ret.first;
return it->second;
}

7、map和multimap的区别

和前面的multiset/set关系相同,就不再赘述。

8、结构化绑定遍历

在遍历map时,c++14可以使用下面的方式来遍历

void test09() {map<string, string> dict1 = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };// 结构化绑定 C++17for (const auto& [k,v] : dict1){cout << k << ":" << v << endl;}cout << endl;
}

在这里插入图片描述

http://www.dtcms.com/a/400509.html

相关文章:

  • 个人博客网站制作搭建医疗网站建设及优化
  • 民族建设集团有限公司官方网站营销什么意思
  • 有没有免费的网站空间九牧全球市场地位
  • 重庆南川网站制作公司哪家好WordPress海报图片插件
  • 大模型微调增加标记、词汇表与嵌入层调整解析(101)
  • 海洋高端的专业做网站数据中台搭建
  • 404网站页面进入做海报的素材网站
  • 设计素材网站排版网站建设的收入来源
  • 建设高端网站快三网站开发
  • 网站logo做黑页网站建设 天佩营销
  • 国内漂亮的企业网站抓取关键词的软件
  • STM32开发(ADC模数转换)
  • 网站建设的风险预测找网站的方法
  • wordpress子域名站点杭州滨江网站开发
  • 什么网站百度的收录高世界企业排名500强
  • 4-3〔O҉S҉C҉P҉ ◈ 研记〕❘ WEB应用攻击▸本地文件包含漏洞-A
  • 以数字域名为网址的网站光谷做网站推广费用
  • 【每日算法】最后一个单词的长度 LeetCode
  • 网站怎么做充值系统美图在线图片编辑器
  • 织梦网站怎样做锚文本学校官网网页设计模板
  • 模电基础:静态工作点稳定的典型电路
  • 潮州网站制作ui做自适应网站
  • 可以做兼职翻译的网站天津住房与城乡建设厅网站首页
  • AIGC实战——BicycleGAN详解与实现:从理论框架到图像翻译核心逻辑
  • todesk设备性能较低,远程过程中出现cpu较高的情况,可以怎么调整?
  • 网站设计与实现wap网站设计方案
  • 企业公司网站 北京wordpress reset
  • 网站建设博客网络推广外包业务怎么样
  • 做网站可以用微软雅黑字体么安卓app用什么开发
  • 四平做网站佳业网络企业网站管理系统标签手册