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

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

在京东面试之后,对程序有了一点感触:数据结构和算法之间,一个程序员首先要考虑最合适的数据模型,之后才是算法,数据模型决定了存取的规模或者复杂度,比如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. libevent入门教程

    首先给出官方文档吧: http://libevent.org ,首页有个Programming with Libevent,里面是一节一节的介绍libevent,但是感觉信息量太大了,而且还是英文的- ...

  2. android系统平台显示驱动开发简要:LCD基本原理篇『一』

    平台信息:内核:linux3.4.39系统:android4.4 平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新浪博客 ...

  3. WinAPI——UnhookWindowsHookEx - 卸掉钩子

    UnhookWindowsHookEx(   hhk: HHOOK {钩子句柄} ): BOOL;    {True/False}

  4. ubuntu12.04升级后找不到共享目录

    备注:采用VMware-workstation 10 更新命令:sudo apt-get update 今天开始搭建Android开发环境,先升级系统,升级后发现windows和ubuntu共享的目录 ...

  5. 【原创】ZYNQ学习笔记(一) HelloWorld实现

    拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...

  6. 中国海洋大学第四届朗讯杯高级组 Cash Cow(模拟)

    题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2721 题意: 给定n个左标,跟那n个坐标 ...

  7. struts2的action中获得request response session 对象

    在struts2中有两种方式可以得到这些对象 1.非IoC方式 要获得上述对象,关键Struts 2中com.opensymphony.xwork2.ActionContext类.我们可以通过它的静态 ...

  8. 深入理解Java虚拟机 - 虚拟机内存划分

    在内存管理方面,Java相对于C和C++的区别在于Java具有内存动态分配以及垃圾收集技术,但平时我们很少去关注JVM的内存结构以及GC,在出现内存泄露或溢出方面的问题,排查工作将变得异常艰难.   ...

  9. 获取QQ所有的表情包,包括emoji,动态gif

    获取QQ所有的表情包,包括emoji,动态gif,代码如下. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xht ...

  10. JavaScript NodeList和Array

    原文引用脚本之家作者:Jeff Wong,谢谢大神提供资源 在Web前端编程中,我们通常会通过document.getElementsByTagName或者document.getElementsBy ...