C++map容器类

map是键-值对的集合,可以理解为关联数组,可以使用键作为下标来获取一个值

本文地址:http://www.cnblogs.com/archimedes/p/cpp-map.html,转载请注明源地址。

map对象的定义

使用前添加map头文件,必须分别指明键和值的类型:

map<string,int>word_count;

map的构造函数:

map<k,v>m;   创建一个名为m的空map对象,其键值类型分别为k和v

map<k,v>m(m2);   创建m2的副本m, m与m2必须有相同的键值类型

map<k,v>m(b,e);   创建map类型的对象,存储迭代器b和e标记的范围内所有元素的副本,元素的类型必须能转化为pair<const k,v>

map定义的类型

map对象的元素是键-值对,map的value_type反映了这样的事实,value_type是存储元素的键以及值的pair类型,而且键为const,比如word_count的类型为:

pair<const string, int>类型

map类定义的类型:

map<K,V>::key_type  在map容器中,用作索引的键的类型

map<K,V>::mapped_type  在map容器中,键所关联的值的类型

map<K,V>::value_type   一个pair类型,它的first元素具有const map<K,V>::key_type类型,而second元素则为map<K,V>::mapped_type类型

map迭代器进行解引用将产生pair类型的对象

map<string,int>::iterator map_it=word_count.begin();
cout<<map_it->first;
cout<<" "<<map_it->second;
map_it->first="new key" //error
++map_it->second

给map添加元素

使用insert成员实现或者先用下标操作符获取元素,然后给获取的元素赋值

使用下标访问map对象

map<string,int>woed_count;  //空map
word_count["Anna"]=1;     //插入默认的初始元素(键:Anna, 值:1)

map的下标也使用索引(就是键)来获取该键所关联的值,如果该键已在容器中,则map的下标运算行为相同,返回该键所关联的值。只有在所查找的键不存在的时候,map容器才为该键创建一个新的元素,并将它插入到此map对象中。

1、下标操作符返回值的使用

下标操作符返回的是左值,即使特定键所关联的值

cout<<word_count["Anna"];
++word_count["Anna"];
count<<word_count["Anna"];

2、下标行为的编程意义

如果下标所表示的键在容器中不在,则添加新元素,这一特性可使程序惊人的简练:

map<string, int>word_count;
string word;
while(cin>>word)
    ++word_count[word];

这段程序用来记录每个单词出现的次数

编程练习:编写程序统计并输出所读入的单词出现的次数

#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<utility>
using namespace std;
int main()
{
    map<string, int> word_count;
    string word;
    while(cin>>word)
        ++word_count[word];
    map<string, int>::iterator it;
    for(it=word_count.begin(); it!=word_count.end(); it++)
        cout<<it->first<<":"<<it->second<<endl;
    return 0;
}

map::insert的使用

插入单个元素的insert版本使用键-值pair类型的参数,对于参数为一对迭代器的版本,迭代器必须指向键-值pair类型的元素

map容器的接受单个值的insert版本的返回类型

使用下标给map添加新元素,元素的值部分将采用值初始化,而插入元素的另一个方法是:直接使用insert成员,语法更紧凑:

word_count.insert(map<string,int>::value_type("Anna",1));

传递给insert的实参相当的笨拙,可以用两种方法简化:

使用make_pair

word_count.insert(make_pair("Anna",1));

或使用typedef:

typedef map<string, int>::value_type valtype;
word_count.insert(valtype("Anna", 1))

检测insert的返回值

如果试图插入的元素所对应的键已经在容器中,则insert将不做任何操作,但是带有一个键-值pair形参的insert版本将返回一个值:包含一个迭代器和一个bool值的pair对象,其中迭代器指向map中具有相应键的元素,而bool值则表示是否插入了该元素

下面使用insert重写的单词统计程序:

#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<utility>
using namespace std;
int main()
{
    map<string, int> word_count;
    string word;
    while(cin>>word) {
        pair<map<string, int>::iterator, bool> ret=word_count.insert(make_pair(word,1));
        if(!ret.second)
            ++ret.first->second;
    }
    map<string, int>::iterator it;
    for(it=word_count.begin(); it!=word_count.end(); it++)
        cout<<it->first<<":"<<it->second<<endl;
    return 0;
}

查找并读取map中的元素

下标操作符读取一个值会产生副作用,map容器提供了两个操作:count和find,用于检查某个键是否存在而不会插入该键

m.count(k)    返回m中k的出现次数

m.find(k)    如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器

1、使用count检查map对象中某键是否存在

对于map对象,count成员的返回值只能是0或1,map容器只允许一个键对应一个实例,所有count可有效地表明一个键是否存在

map<string, int> word_count;
int occurs=0;
if(word_count.count("foo"))
    occurs=word_count["foo"];

2、读取元素而又不插入该元素

find操作返回指向元素的迭代器,如果元素不存在,则返回end迭代器

map<string, int> word_count;
int occurs=0;
map<string,int>::iterator it=word_count.find("foo");;
if(it!=word_count.end())
    occurs=it->second;

从map对象中删除元素

C++map容器类

时间: 2024-09-29 11:06:08

C++map容器类的相关文章

JTSL/EL Expression学习

最早的一个学习笔记,时间过去了久了,供java web初学者参考. JTSL/EL Expression学习安排 学习目标:掌握几个常见标签的使用,通晓工作原理,详细到代码层面,遇到问题时能查得出异常,能排除异常. 学习时间:2天 a) 掌握逻辑判断标签<c:if>,<c:choose>,<c:when>,<c:otherwise> b) 掌握EL表达式页面隐式对象:requestScope,sessionScope,pageScope,pageContex

c++fstream文件读写(与java的比较)

一:起因 (1)之前处理文本数据时,各种清洗数据用的都是java的File,FileReader/FileWriter,BufferedReader/BufferedWriter等类,详见java读写文本文件 (2)应用java的原因是java里面的map非常灵活,eclipse编译器更是给力,而且ctrl 可以追踪函数 等,详见java map的排序 (3)应用java的另一个原因是java里面的string类的字符串处理非常灵活,各种函数是应用尽有. (4)上面两点算是自己的误解吧,因为c+

Go Programming Blueprints 读书笔记(谈到了nsq/mgo处理数据持久化,但是业务逻辑不够复杂)

Go Programming Blueprints http.Handle("/", &templateHandler{filename: "chat.html"}); http.Handle静态方法? 带参数的函数对象参数? 就是个普通的struct--为何不需要new? go get github.com/gorilla/websocket(方便的包依赖管理!) Go语句不需要:标记结束 TDD: 在没有定义type struct之前假设已经存在? 控制

c++ fstream + string 处理大数据

一:起因 (1)之前处理文本数据时,各种清洗数据用的都是java的File,FileReader/FileWriter,BufferedReader/BufferedWriter等类,详见java读写文件 (2)应用java的原因是java里面的map非常灵活,eclipse编译器更是给力,而且ctrl 可以追踪函数 等,详见java map的排序 (3)应用java的另一个原因是java里面的string类的字符串处理非常灵活,各种函数是应用尽有. (4)上面两点算是自己的误解吧,因为c++里

【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别

原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别. 经常会看到程序中使用了记录集,常用的有Collection.HashMap.HashSet.ArrayList,因为分不清楚它们之间的关系,所以在使用时经常会混淆,以至于不知道从何下手.在这儿作了一个小例

Java的容器类Collection和Map

一,概念 java的容器类一共有两种主要类型,Colllection和Map. 两者的区别是:Collection是单个元素,而Map是存储一个键值对 两者的子类关系如下图所示: 二,子类介绍 1,Collection的子类如下: List:将以特定次序存储元素,所以取出来的顺序可能和放入的顺序不同 ArrayList:擅长随机访问元素,但在List中间插入,删除,移动元素较慢 LinkedList,插入,删除,移动元素方便,随机访问元素差 Set:每个值只能保存一个对象,不能包含重复的元素 H

Java中的容器类(List,Set,Map,Queue)

Java中的容器类(List,Set,Map,Queue) 一.基本概念 Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念: 1)Collection.一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素,而Set不能有重复的元素.Queue按照排队规则来确定对象产生的顺序(通常与它们被插入的顺序相同). 2)Map.一组成对的“键值对”对象,允许你使用键来查找值.ArrayList允许你使用数字来查找值,因此在某种意义上讲,它将数字与对象关联在

Java容器类接口:Iterator,Collection,Map

Iterator Iterator被称为迭代器,是一个对象,它的工作是遍历并选择序列中的对象,可以实现以下一些操作: 使用方法iterator()要求容器返回一个Iterator,Iterator将返回序列的第一个元素: 使用next()获取序列中的下一个元素: 使用hasNext()检查序列中是否有元素: 使用remove()将迭代器最近返回的元素删除: Iterator只能向前移动,ListIterator是一个更加强大的Iterator的子类,它只能用于各种List类的访问,ListIte

Java源码解析容器类List、Set、Map

1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程安全,效率低 LinkedList 底层数据结构是链表,查询慢,增删快 线程不安全,效率高 Set(无序,唯一) HashSet 底层数据结构是哈希表. 哈希表依赖两个方法:hashCode()和equals() 执行顺序: 首先判断hashCode()值是否相同 是:继续执行equals(),看其