C++进阶-- map和set

简介: C++进阶-- map和set

关联式容器

在前面,我们所学的vector、list、deque,这些都是序列容器,也就是底层为线性序列的数据结构。

而关联式容器是C++标准库中的一种类别,用于存储键值对(key-value pair),关联式容器中的元素中的元素是按照键值进行有序存储的,同时也支持快速查找、插入、修改等操作。而map和set就是主要的类型;

这些关联式容器在实现上通常采用平衡二叉搜索树或哈希表等数据结构来保证元素的有序性和高效的查找性能。

键值对

键值对是关联式容器中的一种结构,它由一个键(key)和一个对应值(value)组成。在关联式容器中,每个元素都有一个唯一的键,用于标识和访问该元素。键值对的特性使得关联式容器能够通过键快速查找、插入、删除。

在关联式容器中,键通常用于确定元素的顺序和唯一性,而值则是与键关联的数据。键和值可以是任何类型,但通常使用类或结构体作为键类型,以提供自定义的比较规则。通过比较键的值,关联式容器能够按照键的顺序进行有序存储,并支持快速的查找操作。

键值对的定义:

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)
{}
};

set

介绍

set是C++标准库中的一种关联式容器,它用于存储一组有序的、唯一的元素。set中的元素按照键值进行自动排序,并且不允许存在重复的元素

set在底层是由二叉搜索树(红黑树)实现的。

set中只放value,但在底层实际存放的是由<vlaue,value> 构成的键值对。

set中查找某个元素时,时间复杂度为:log_2 n .

使用

void test1()
{
  set<int> s;
  s.insert(1);
  s.insert(3);
  s.insert(3);
  s.insert(4);
  s.insert(6);
  s.insert(9);
  s.insert(7);
  set<int>::iterator it = s.begin();
  while (it != s.end())
  {
    cout << *it << " " ;
    it++;
  }
  cout << endl;
  // 使用迭代器逆向打印set中的元素
  for (auto it = s.rbegin(); it != s.rend(); ++it)
  {
    cout << *it << " ";
  }
  cout << endl;
  set<int>::iterator pos = s.find(7);
  if (pos != s.end())
  {
    cout << "找到了" << endl;
    s.erase(pos);
  }
  
}

void test2()
{
  set<int> s;
  s.insert(1);
  s.insert(3);
  s.insert(3);
  //s.insert(4);
  s.insert(6);
  s.insert(9);
  s.insert(7);
  auto start = s.lower_bound(4);
  cout << *start << endl;
  auto finish = s.upper_bound(4);
  cout << *finish << endl;
}

muiltiset

multisetsC++标准库中的一种关联式容器,它与set容器类似,但允许存储重复的元素

muiltiset容器和set容器的主要区别在于对重复元素的处理。在set容器中,每个键值只能出现一次,而在muitiset容器中,同一个键值可以出现多次。multisey中的元素会根据键值自动进行排序。

void test3()
{
  multiset<int> s;
  s.insert(5);
  s.insert(1);
  s.insert(6);
  s.insert(3);
  s.insert(4);
  s.insert(5);
  s.insert(1);
  s.insert(1);
  s.insert(5);
  s.insert(1);
  s.insert(1);
  s.insert(2);
  s.insert(7);
  s.insert(10);
  multiset<int>::iterator it = s.begin();
  while (it != s.end())
  {
    cout << *it << " ";
    ++it;
  }
  cout << endl;
  //统计相同元素的个数
  cout << s.count(1) << endl;
  cout << s.count(5) << endl;
}

map

介绍

map是C++标准库中的一种关联式容器,它用于存储一组键值对每个元素都由一个唯一的键和对应的值组成。map中的元素按照键进行自动排序,并且不允许存在重复键

在map内部,key和value通过成员类型value_type绑定在一起,为其取别名为pair;

typedef pair<const key,T> value_type;

map支持下标访问符,即在[]中放入key,就可以找到与key对应的value值;

map通常被实现为二叉搜索树(平衡二叉搜索树).

使用

void test4()
{
  map<string, string> dict;
  dict.insert(pair<string, string>("sort", "排序"));
  //pair<string, string> kv("string", "字符串");
  pair<string, string> kv = { "string", "字符串" };
  dict.insert(kv);
  // C++11 多参数隐式类型转换(构造函数)
  dict.insert({ "apple", "苹果" });
  // C++98
  dict.insert(make_pair("sort", "排序"));
  for (auto& kv : dict)
  {
    cout << kv.first << ":" << kv.second << endl;
  }
  cout << endl;
}

void test5()
{
  string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
"苹果", "香蕉", "苹果", "西瓜", "香蕉", "草莓" };
  map<string, int> countMap;
  for (auto& e : arr)
  {
    countMap[e]++;
  }
  for (auto& kv : countMap)
  {
    cout << kv.first << ":" << kv.second << endl;
  }
  cout << endl;
  //通过operator[]进行查找value值
  cout << countMap["苹果"] << endl;
}

multimap

multimapC++标准库中的一种关联式容器,它与map容器类似,但允许存储重复的键

multimap容器和map容器的主要区别在于对重复键的处理方式。在multimap中,可以有很多个元素具有相同的键,这些元素会按照键进行自动排序,但不保证值的顺序

multimap中没有重载operator[]操作;

使用时与map包含的头文件相同。

相关文章
|
4天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
17 3
|
1月前
|
存储 自然语言处理 C++
map和set的简单介绍
map和set的简单介绍
20 1
|
5天前
|
存储 搜索推荐 C++
【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构
【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构
|
5天前
|
设计模式 C语言 C++
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
|
5天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
|
5天前
|
算法 C++ 容器
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
|
5天前
|
编译器 C++
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析
|
24天前
|
存储 JavaScript 前端开发
set和map的区别
set和map的区别
35 4
|
1月前
|
存储 算法 C语言
【C++入门到精通】C++入门 —— map & multimap (STL)
之前我们学习了C++的基础和一些概念,现在将探讨重要的STL组件——map与multimap。map是关联容器,提供有序键值对存储,基于红黑树,支持高效查找、插入和删除。每个键唯一对应一个值。multimap则允许键的重复。两者都提供迭代器支持,但map的键是唯一的,而multimap允许键重复,插入和查找效率不同。更多详情,请查阅官方文档。祝学习愉快!
12 0
|
1月前
|
存储 算法 C++
【C++ map结构 】std::map 和 std::unordered_map 在使用上的差异
【C++ map结构 】std::map 和 std::unordered_map 在使用上的差异
22 0