map与set的原理及使用

来源:互联网 发布:淘宝联盟分享能赚钱吗 编辑:程序博客网 时间:2024/06/06 03:18
   众所周知C++比C的使用更加灵活是由于C++中有大量的库函数。今天我们所研究的是其中的map与set。
  1.set
     底层实现是红黑树,元素的键值是实数、它的特性及用途 可将元素的键值value按升序输出  防冗余  用来判断正误
set的接口有许多,我们研究比较常用的。如begin end size此类与之前库函数大抵相似,用法无二,不做研究。
insert
      single element (1)
pair<iterator,bool> insert (const value_type& val);
with hint (2)
iterator insert (iterator position, const value_type& val);
range (3)
template <class InputIterator>  void insert (InputIterator first, InputIterator last);
 insert有三种,第一种参数为value_type类型,根据元素键值类型所决定的。返回值是pair结构体,结构体由迭代器和一个bool类型构成,bool表示是否插入成功,若原先没有则插入成功,迭代器存放指针存放该元素,若原先有这个实数则插入不成功,迭代器指向最后一个元素的下一位置。第二种与第一相似。第三种不常用我们就不一一分析。

find
  用法:iterator find (const value_type& val) const;有
        find的参数为value上面有说过在set中元素的键值是实数,用const 防止value被改变破坏底层结构。返回值为iterator,这是我们关注的重点,返回的是一个指针,若存在就会返回元素的位置,若不存在就会出现断言错误。
    void fun1()
{
 set<int> s1;
 set <int>::iterator it;
 s1.insert(10);
 s1.insert(9);
 s1.insert(110);
 s1.insert(1);
 s1.insert(15);
 it = s1.find(10);
 it = s1.find(100);
 cout << *it << endl;
}
2.map
   map的底层实现同样为红黑树,与set不同的是它元素是 K V结构,即元素为一个由value和key组成的pair结构体,
typedef pair<const Key, T> value_type;
它同样具有使元素按键值升序的特性,map与set都是底层实现时利用红黑树中序遍历实现的。下图为map比较常用的接口。我们将研究其中比较典型的。
insert
 下列是关于insert的三种说明方法。
pair<iterator,bool> insert (const value_type& val);
with hint (2)
iterator insert (iterator position, const value_type& val);
range (3)
template <class InputIterator>  void insert (InputIterator first, InputIterator last);

第一种与set大抵相似,不同点在value_type,map所对的是value和key。还有返回值pair结构体中多了key,所以可对返回值做操作。
map<string,int> m1;
 m1.insert(pair<string, int>("hello", 1));
 std::pair<map<char, int>::iterator, bool> ret;//pair结构体,参数一迭代器(指向map元素),参数二bool是否插入成功
 ret = m1.insert(std::pair<string, int>("bit", 500));
用ret接受返回值,可对 ret.first->second进行操作,代表的是map中的key值。其他不做介绍。

find
find共有两种,区别是const修饰,如下:
   iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
以第一种为例,参数我们在之前已经讲过,返回值为迭代器 ,指向map元素。
operator[]
 这是map的一个亮点,用法mapped_type& operator[] (const key_type& k)。


用法
下面是利用map实现调查一个公司员工喜欢水果次数与最喜欢的前K水果

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#include <set>


struct Compare
{
 bool operator()(pair<string, int> p1, pair<string, int> p2)
 {
  return p1.second > p2.second;
 }
};
//统计公司里面最受员工欢迎的topK种水果
void  CountTopK(const vector<string>& v)
{
 map<string, int> fruit;
 map<string, int>::iterator it;
 
 
 for (size_t i = 0; i < v.size(); i++)
 {
  fruit[v[i]]++;
 }
 it = fruit.begin();
 vector<pair<string, int> > v2;
 while (it != fruit.end())
 {
  v2.push_back(pair<string, int>(it->first, it->second));
  ++it;
 }
 make_heap(v2.begin(), v2.end(), Compare());
 sort_heap(v2.begin(), v2.end(), Compare());
}


template <typename K, typename V>
 void CountTopK(string fruits[], size_t sz, const map<K, V> &m)
{
 map <string, int> count;
 for (size_t i = 0; i < sz; ++i)
 {
  //方法1
  map <string,int>::iterator it = count.find(fruits[i]);
  if (it != count.end())
  {
  it->second++;
  //*(it).second++;
  }
  else
  {
  count.insert(pair<string,int>(fruits[i],1));
  }

 

  //方法3
  count[fruits[i]]++;
 }
 //将迭代器导入vector
 vector<map<string, int>::iterator> heap;
 map<string, int>::iterator mapIt = count.begin();
 while (mapIt != count.end())
 {
  heap.push_back(mapIt);
  ++mapIt;
 }
 //建小堆
 struct Com
 {
  bool operator()(const map<string, int>::iterator l, const map<string, int>::iterator r)
  {
   return l->second < r->second;
  }
 };
 sort(heap.begin(), heap.end(), Com());

 make_heap(heap.begin(),heap.end(),Com());
 int diff = heap.size() - k;
 //向下调整
 while(diff--)
 {
 pop_heap(heap.begin(),heap.end(),Com());
 heap.pop_back();
 }
 //输出结果
 while (heap.size() != 0)
 {
  cout << heap.back()->first << ":" << heap.back()->second << endl;
  heap.pop_back();
 }
}

int main()
{
 map <string, int> count;
 string fruits[] = { "apple", "banana", "orange", "pineapple", "grape",
  "banana", "orange", "apple", "apple", "orange",
  "pineapple", "grape", "orange", "pineapple", "pear",
  "grapefruit", "mango", "mango juice", "apple",
  "Hami melon", "melon", "peach", "banana",
  "pineapple", "grape", "orange", "pineapple", "pear",
  "grapefruit", "mango", "apple", "melon", "peach", "banana",
  "melon", "peach", "banana", "Hami melon",
  "pineapple", "grape", "orange", "pineapple", "pear",
  "grapefruit", "mango", "peach", "peach" };
 size_t sz = sizeof(fruits) / sizeof(fruits[0]);
 
 (fruits, sz, count);
 system("pause");
 return 0;
}















  

 
 
  
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米6相机卡顿怎么办 华为手机玩游戏发热怎么办 华为手机变慢了怎么办 华为p10手机变慢怎么办 华为手机账户密码忘记了怎么办 QQ浏览器无法加载插件怎么办 电脑开了机黑屏怎么办 扫描仪打不开运单扫描怎么办 打印机不支持64位系统怎么办 xp系统dnf闪退怎么办 w10电脑所有程序都打不开怎么办 安卓手机太卡怎么办 系统装到f盘了怎么办 虚拟机占c盘内存怎么办 外机连无线虚拟机显示受限怎么办 使用msdn下载解压后怎么办 路由80端口被占用怎么办 c盘拒绝粘贴文件怎么办 oracle数据库密码忘了怎么办 电脑开机时不显示用户名怎么办? xp系统忘记开机密码怎么办 电脑开机密码忘了怎么办 c盘满了怎么办win10 win10电脑开机密码忘了怎么办 win10的开机密码忘了怎么办 u盘中了exe病毒怎么办 眼睛长个麦粒豆怎么办 苹果手机sdk授权失败怎么办 小米5王者荣耀卡怎么办 华为p9手机电池不耐用怎么办 华为g9青春版耗电快怎么办 华为手机摄像头坏了怎么办 华为p10摄像头玻璃划痕怎么办? 华为g9手机音量小怎么办 华为7pius太卡怎么办 华为畅享7plus卡怎么办 华为p9屏幕进水变颜色怎么办? 玩王者荣耀卡退怎么办 华为手机忘记开机密码怎么办 华为p9密码忘了怎么办 华为p9解锁密码忘了怎么办