技术不只是我的工作,也是我的生活,以后的博客中会穿插一些个人的喜悦、愤怒或者感悟,希望大家能够接受。

我所有的一切,比我技术更好的怕是我的脸皮了,昨天收到京东面试没有通过的消息,喊了几句“我好悲伤啊”就又能够继续我的生活了。呵呵,我不喜欢批判,但总是能看到自己的不足,好吧,这是一个痛并快乐的过程,我要造作的喊“悲伤”,我想放纵让亲友安慰我,我也要悄悄的学习,只为证明:我也很强,以后会更强。

在京东面试之后,对程序有了一点感触:数据结构和算法之间,一个程序员首先要考虑最合适的数据模型,之后才是算法,数据模型决定了存取的规模或者复杂度,比如10亿个URL,判断某一个URL是否在其中,我们可以设计一个比较长的字符串,通过 hash算法将每一个URL映射至字符串的5个位置,如果5个位置均为1,就代表了URL存在其中;又比如经典的火车进站出站问题,如果能想到栈和队列的模型就很容易解决。

map的特性、用途&用法

map称作映射或者关联数组,可以用来取代程序中一些很令人讨厌且低效率的线性匹配,提高效率和可读性。

map是一种(关键码,值)对偶的表,还很对基于关键码去查询做了特殊的优化。map的使用可以理解成一种下表不必是整数值的数组。

map和传统的关联数组,每个关键码相关联有唯一的一个值,,multimap允许元素中出现重复关键码,set和multiset可以看做是退化的关联数组,其中没有与关键码关联的值。

map提供双向迭代器,并要求其关键码类型提供一个小于操作以保持元素的有序性;对于那些没有明显顺序的元素,或者不必保持容器有序的情况,我们可以考虑用hash_map。

map中关键码是对偶的第一个元素,映射值是第二个;对任何pair,我们总是用first和second索引其第一个和第二个元素;pair的用途也不仅限于map的实现,pair本身也是一个标准库类,pair可以用make_pair快速创建。

map的特征性操作:采用下表运算法提供的关联查找。

map的下标操作和find该用哪个?

map的下标运算符[]将关键码作为下标去执行查找,如果关键码不存在,则插入一个具有该关键码和mapped_type类型默认值的元素至map中,因此下标运算符[]在map应用中需要慎用,const_map不能用,只希望确定某一个关键值是否存在而不希望插入元素时也不应该使用,mapped_type类型没有默认值也不应该使用。如果find能解决需要,尽可能用find。

map插入和删除元素:

map最方便的插入元素方式是下标操作;map也可以通过insert插入元素和erase删除元素,clear清除所有元素。insert和erase与其他STL容器不同,没有迭代器参数,返回值也是一个pair。erase的返回值是成功删除的元素个数,通过这个值我们可以判断要删除的关键码是否存在map中。

multimap

multimap支持重复关键码的数据,因此不支持下标操作;multimap的insert操作总是成功的并返回迭代器,equal_range、lower_bound、upper_bound是用关键码访问多重元素的基本手段。

set

一个set也可以看做一个map,其中的值是无关紧要的,只保留了关键码;set依靠的是比较操作(默认为<)而不是相等(==),这隐含着元素的相等需要由不相等定义,而且迭代通过set是有序的;不支持下标操作。

multiset

一种允许重复关键码的set ,通过equal_range、lower_bound、upper_bound操作访问重复关键码。

关于map的后台实现

map后台基于红黑树,一种非典型的平衡二叉树。

小结

map和set是STL中很有用的数据结构,应用非常广泛,STL的容器应用非常广泛,甚至可以这么说:学会了所有的STL用法和特性以后,除非必要很少会用到基本的数组和链表。

补充 

用multimap实现了一个电话簿程序,包括插入、查找、删除,允许同一个联系人拥有多个联系方式:

#include<iostream>
#include<map>
#include<string>
using namespace std;
multimap<string, string> book;
int main()
{
string name, num, op;
multimap<string, string>::iterator itorlower;
multimap<string, string>::iterator itorupper;
cout << "telephone book DEMO" << endl;
while (1)
{
name.clear();
num.clear();
op.clear();
cout << "input your select" << endl;
cout << "1.Add new linkman" << endl;
cout << "2.query linkman" << endl;
cout << "3.delete linkman" << endl;
cout << "4.quit" << endl;
cin >> op;
if (!op.compare("1"))
{
cin >> name;
cin >> num;
if ((itorlower = book.lower_bound(name)) != book.end())
{
itorupper = book.upper_bound(name);
for (;itorlower != itorupper; itorlower++)
{
if (!itorlower->second.compare(num))
{
cout << "linkman and telephone num already exist" << endl;
break;
}
}
if (itorlower == itorupper)
book.insert(make_pair(name, num));
}
else
{
book.insert(make_pair(name, num));
}
}
else if (!op.compare("2"))
{
cin >> name;
if ((itorlower = book.lower_bound(name)) != book.end())
{
itorupper = book.upper_bound(name);
for (;itorlower != itorupper; itorlower++)
{
cout << "linkman " << itorlower->first << " num " << itorlower->second << endl;
}
}
}
else if (!op.compare("3"))
{
cin >> name;
while ((itorlower = book.lower_bound(name)) != book.end())
{
book.erase(itorlower);
}
}
else if (!op.compare("4"))
{
break;
}
else
{
cout << "input error, try again" << endl;
}
}
return 0;
}

【STL学习】map&set的更多相关文章

  1. STL学习 - map

    C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值. 一.map的说明    1   头文件 #include <map> 2  ...

  2. map--C++ STL 学习

    map–C++ STL 学习   Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力.   说下map内 ...

  3. STL的pair学习, map学习

    http://blog.csdn.net/calvin_zcx/article/details/6072286 http://www.linuxidc.com/Linux/2014-10/107621 ...

  4. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

  5. 侯捷STL学习(九)--关联式容器(Rb_tree,set,map)

    layout: post title: 侯捷STL学习(九) date: 2017-07-21 tag: 侯捷STL --- 第十九节 容器rb_tree Red-Black tree是自平衡二叉搜索 ...

  6. 侯捷STL学习(十)--容器hashtable探索(unordered set/map)

    layout: post title: 侯捷STL学习(十) date: 2017-07-23 tag: 侯捷STL --- 第二十三节 容器hashtable探索 hashtable冲突(碰撞)处理 ...

  7. STL学习小结

    STL就是Standard Template Library,标准模板库.这可能是一个历史上最令人兴奋的工具的最无聊的术语.从根本上说,STL是一些"容器"的集合,这些" ...

  8. 标准模板库(STL)学习探究之stack

    标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string

  9. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  10. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

随机推荐

  1. Android日期时间选择器实现以及自定义大小

    本文主要讲两个内容:1.如何将DatePicker和TimePicker放在一个dialog里面:2.改变他们的宽度: 问题1:其实现思路就是自定义一个Dialog,然后往里面同时放入DatePick ...

  2. Android view的requestLayout()

    public void requestLayout () Since: API Level 1 Call this when something has changed which has inval ...

  3. PostgreSQL和MySQL like区别

    前言:今天在PostgreSQL中使用like,字段类型是int,执行语句报错, 1.表结构:都是用sysbench工具产生的 postgres=# \d sbtest1;               ...

  4. Android 常用UI控件之TabHost(5)Tab栏在底部且在最上层也不盖tab页

    tab栏在底部 <TabHost android:id="@android:id/tabhost" android:layout_width="match_pare ...

  5. Android开发框架之xUtils学习

    1.一个非作者弄的xUtils API文档: http://xutilsapi.oschina.mopaas.com/overview-summary.html 2.使用xUtils用户的一些博客文档 ...

  6. 转载:C++ list 类学习笔记

    声明:本文转自http://blog.csdn.net/whz_zb/article/details/6831817 双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面 ...

  7. 设置一个POJO的某个属性的默认值

    //月利率private BigDecimal monthRate=new BigDecimal(0);  

  8. CSS基础深入之细说盒子模型

    Html任何一个元素(element)都可以当成一个盒子(box)来看待,可以结合现实中的盒子来理解下文,下文其中一些单词应该是通俗易懂的需要记录的单词. 基本情况 每一个盒子都有一个内容区域(con ...

  9. Asp.Net MVC 模型(使用Entity Framework创建模型类) - Part.1

    这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...

  10. Linux 下操作gpio(两种方法,驱动和mmap)

    目前我所知道的在linux下操作GPIO有两种方法: 1.  编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...