1.map和set的应用和比较

  map和set都是关联式容器,底层容器都是红黑树。

  map以键值对的形式进行存储,方便进行查找,关键词起到索引的作用,值则表示与索引相关联的数据,以红黑树的结构实现,插入删除等操作都可以在O(log n)时间内完成。

  • 所有元素都是键+值存在,key=value组成pair,是一组映射关系。
  • 不允许键重复
  • 所有元素是通过键进行自动排序的
  • map的键是不能修改的,但是其键对应的值是可以修改的
 #include<string>
#include<vector> //模拟pair和 make_pair的底层实现
//template<class K, class V>
//struct pair
//{
// K first;
// V second;
//
// pair(const K& key, const V& value)
// :first(key)
// , second(value)
// {}
//};
//template<class K, class V>
//pair<K, V> make_pair(const K& key, const V& value)
//{
// return pair<K, V>(key, value);
//} //vector<string> GetTopKF(const vector<string>& fruits)
//{
// vector<string> topk;
// typedef map<string, int> CountTop;
// typedef map<string, int>::iterator CountIt;
// CountTop counttop;
// for (size_t i = 0; i < fruits.size(); i++) {
// CountIt countit = counttop.find(fruits[i]);
// if (countit != counttop.end())
// (countit->second)++;
// else
// //counttop.insert(pair<string, int>(fruits[i], 1));
// counttop.insert(make_pair(fruits[i], 1));
// }
// return topk;
//}
vector<string> GetTopKF(const vector<string>& fruits)
{
vector<string> topk;
typedef map<string, int> CountTop;
typedef map<string, int>::iterator CountIt;
CountTop counttop;
for (size_t i = ; i < fruits.size(); i++) {
/*pair<CountIt, bool> retKV = counttop.insert(make_pair(fruits[i], 1));
if (retKV.second == false)
{
retKV.first->second++;
}*/
counttop[fruits[i]]++;
}
return topk;
} void MapTest()
{
typedef map<string, string> Dict;
typedef map<string, string>::iterator DictIt;
Dict dict;
dict.insert(pair<string, string>("right", "右边"));
dict.insert(pair<string, string>("left", "左边"));
dict.insert(pair<string, string>("世界", "你好"));
dict.insert(pair<string, string>("hello", "word"));
dict.insert(pair<string, string>("key", "键值")); DictIt dictit = dict.begin();
while (dictit != dict.end()) {
cout << (*dictit).first << " " << (*dictit).second << endl;
++dictit;
}
DictIt ret = dict.find("left");
if(ret != dict.end())
dict.erase(ret);
vector<string> v;
v.push_back("梨");
v.push_back("苹果");
v.push_back("西瓜");
v.push_back("香蕉");
v.push_back("西瓜");
v.push_back("香蕉");
v.push_back("菠萝");
v.push_back("西瓜");
v.push_back("草莓");
GetTopKF(v);
}

  set支持高效的关键字查询操作---检查每一个给定的关键字是否在set中,也支持高效插入删除。

  以平衡二叉检索树实现,查找使用中序遍历算法,检索效率高于vector,deque,list等容器,另外使用中序遍历可将键值按照从小到大遍历出来,构造set集合的主要目的是为了快速检索,不可直接去修改键值。
  • 所得元素的只有key没有value,value就是key
  • 不允许出现键值重复
  • 所有的元素都会被自动排序
  • 不能通过迭代器来改变set的值,因为set的值就是键
 #pragma once
#include<iostream>
#include<set>
#include<map> using namespace std; void SetTest()
{
set<int> s1; //没有数据冗余
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert();
s1.insert(); //set的插入操作 set<int>::iterator ite = s1.begin();
//ite = 10;
while (ite != s1.end()) { //利用迭代器遍历打印数据
cout<<*ite<<" ";
ite++;
}
cout << endl;
set<int>::reverse_iterator ret1= s1.rbegin();
while (ret1 != s1.rend()) { //降序打印
cout << *ret1 << " ";
ret1++;
} set<int>::iterator ret = s1.find(); //
if (ret != s1.end()) //set的查找,如果没有找到不会报错
cout << "find it" << *ret << endl;
else
cout << "null" << endl; if (s1.count())//只判断是否存在14,返回1或0
cout << "find it" << endl;
else
cout << "null" << endl; ret = s1.find(); //find后删除
if (ret != s1.end())
s1.erase(ret);
set<int>::iterator last, first;
first = s1.lower_bound(); //返回8大的第一个数
last = s1.upper_bound(); //返回20大的第一个数
s1.erase(first, last);//删除这个范围的数据
s1.erase(); //有就删除,没有也不报错 set<int>::iterator ite1 = s1.begin();
while (ite1 != s1.end()) {
cout << *ite1 << " ";
ite1++;
}
}
void MultisetTest() {
multiset<int> s2; //允许数据冗余,其他操作同set
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
s2.insert();
multiset<int>::iterator mit = s2.begin();
while (mit != s2.end()) {
cout << *mit << " ";
mit++;
}
multiset<int>::iterator mIt = s2.find();
/*++mIt;
++mIt;
++mIt;
++mIt;*/
}

  map的节点是一对数据,set的节点是一个数据。

2.扩展

  Multimap允许数据冗余,即存储的数据不唯一。
  hashmap是基于散列表(哈希表,hash table)实现的。基本原理是:使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数,也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标,hash值)相对应,于是用这个数组单元来存储这个元素;也可以简单的理解为,按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方,称为桶。
但不能够保证每个元素的关键字与函数值是一一对应的,有可能出现对于不同的元素,得到相同的函数值,这就是哈希冲突,往往需要专门的哈希冲突处理函数来解决。
  hashma插入和查找的速度与 哈希函数和冲突处理函数的 实现有关,是这两个函数耗时的总和。查询时间复杂度是O(1);
看具体的应用,不一定常数级别的hash_map一定比log(n)级别的map要好,hash_map的hash函数以及解决地址冲突等都要耗时间,而且众所周知hash表是以空间换时间的,因而hash_map的内存消耗肯定要大,一般情况下,如果记录非常大,考虑hash_map,查找效率会高很多,如果要考虑内存消耗,则要谨慎使用hash_map。
  Multiset允许数据冗余。

map和set的使用及top K问题的更多相关文章

  1. 347. Top K Frequent Elements (sort map)

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  2. 347. Top K Frequent Elements

    Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...

  3. [LeetCode] Top K Frequent Words 前K个高频词

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  4. 海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

    前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些. 先拿10000个数建堆, ...

  5. 如何解决海量数据的Top K问题

    1. 问题描述 在大规模数据处理中,常遇到的一类问题是,在海量数据中找出出现频率最高的前K个数,或者从海量数据中找出最大的前K个数,这类问题通常称为“top K”问题,如:在搜索引擎中,统计搜索最热门 ...

  6. [leetcode]692. Top K Frequent Words K个最常见单词

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  7. [leetcode]347. Top K Frequent Elements K个最常见元素

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  8. top k问题

    1.top k问题 在海量数据处理中,经常会遇到的一类问题:在海量数据中找出出现频率最高的前k个数,或者从海量数据中找出最大的前k个数,这类问题通常被称为top K问题.例如,在搜索引擎中,统计搜索最 ...

  9. 【分步详解】两个有序数组中的中位数和Top K问题

    (这也是一道leetcode的经典题目:<LeetCode>解题笔记:004. Median of Two Sorted Arrays[H] 问题介绍 这是个超级超级经典的分治算法!!这个 ...

随机推荐

  1. Spring Boot (十二): Spring Boot 邮件服务

    最早我们发邮件的时候是使用 JavaMail 来发送邮件,而在 Spring Boot 中, Spring Boot 帮我们将 JavaMail 封装好了,是可以直接拿来使用的. 1. 依赖文件 po ...

  2. IoC 之加载 Bean:总结

    上文中我们将bean已经加载到了IOC容器中,接下来我们将把IOC加载Bean出来进行代码解析 备注:(有些解释是参考别个博客的相关解释 )一起探讨请加我QQ:1051980588 bean 的初始化 ...

  3. 【DP合集】m-knapsack

    给出 n 个物品,第 i 个物品有重量 w i .现在有 m 个背包,第 i 个背包的限重为 c i ,求最少用几个背 包能装下所有的物品. Input 输入的第一行两个整数 n, m ( n ≤ 2 ...

  4. 推荐一款超好用的工具cmder

    今天来推荐一个超级好用的命令行工具:cmder 一款Windows环境下非常简洁美观易用的cmd替代者,它支持了大部分的Linux命令.支持ssh连接linux,使用起来非常方便.比起cmd.powe ...

  5. mysql的十二条基本语句

    在 mysql里,所有语句都以分号作为结束标志! 1.连接服务器 Mysql -u username -p passwd 2.当连上服务器后,首先面对的是库,库有1个或多个,因此我们想对表进行操作的话 ...

  6. 张高兴的 .NET Core IoT 入门指南:(五)串口通信入门

    在开始之前,首先要说明的是串口通信所用到的 SerialPort 类并不包含在 System.Device.Gpio NuGet 包中,而是在 System.IO.Ports NuGet 包中.之所以 ...

  7. PowerBI系列之入门案例动态销售报告

    本文将讲解如何从零开始使用PowerBI Desktop制作一份动态销售报告.帮助大家快速入门PowerBI Desktop的操作.我们先来看一下一份动态销售报告的构成. 1.左上角放置了小黎子数据分 ...

  8. wwindows权限认识(用户及用户组)

    windows权限认识(用户及用户组) Windows系统内置了许多本地用户组,这些用户组本身都已经被赋予一些权限(permissions),它们具有管理本地计算机或访问本地资源的权限.只要用户账户加 ...

  9. [Luogu2422]良好的感觉

    题目描述 kkk做了一个人体感觉分析器.每一天,人都有一个感受值Ai,Ai越大,表示人感觉越舒适.在一段时间[i, j]内,人的舒适程度定义为[i, j]中最不舒服的那一天的感受值 * [i, j]中 ...

  10. python里怎么查看数据类型

    python里怎么查看数据类型? python里可以通过type()函数来查看数据类型. Python 内置函数 Python 内置函数 Python type() 函数如果你只有第一个参数则返回对象 ...