map与multimap

map与multimap其实与set与multiset差不多,set与multiset是一种特殊的map与multimap。其再命名空间的定义如下:

namespace std{
	template <class key, class t,
						class compare = less<key>,
						class allocator = allocator<pair<const key, t>>>
	class map ;
	
	template <class key, class t,
						class compare = less<key>,
						class allocator = allocator<pair<const key, t>>>
	class multimap ;

}
其第一个参数是key,第二个参数是value,和所有标准的关联式容器一样,map/multimap也是平衡二叉树,set中value,key指向同一个对象,map元素是key/value的pair,map可以作为关联式数组使用,map也是通过key的值进行排序的,所以搜索元素有很好的性能,其key是const类型,不可以直接改变,要修改的话必须先删除这个元素,再插入一个新的,但value是可以改变的。

访问其中元素的方法如下:

std::map<std::string, float> coll ;
std::map<std::string, float>::iteraror pos ;
for (pos = coll.begin(); pos != coll.end(); ++pos)
{
	std::cout << pos->first << pos->second ;
}
安插一个key/value pair的时候,在map/multimap内部,key被视为常数,所以要不提供正确的型别,要不提供隐式或显示型别转换,有个三个方法可以插入value到map

  1. 运用value_type

为了避免隐式的型别转换,可以运用value_type明白传递正确的型别,value_type是容器本省提供的型别定义

std::map<std::string, float> coll ;
coll.insert(std::map<std::string, float>::value_type("otto", 22.3)) ;
       2.运用pair<>

std::map<std::string, float> coll ;
coll.insert(std::pair<std::string, float>("otto", 22.3)) ;
coll.insert(std::pair<const std::string, float>("otto", 22.3)) ;//这个类型不同,需要转换,insert需要定义成member template
      3.运用make_pair

std::map<std::string, float> coll ;
coll.insert(std::make_pair("otto", 22.3)) ;//这个也需要member template来执行类别转换
map的insert函数的返回值和set差不多,也可以判断是否成功

这里有个关于迭代器失效的例子:

typedef std::map<std::string, float> StringFloatMap ;
StringFloatMap coll ;
StringFloatMap::iterator pos ;
for (pos = coll.begin(); pos != coll.end(); ++pos)
{
	if (pos->second == value)
		coll.erase(pos) ;//对pos所指元素实施erase(),会使pos成为一个有效的迭代器,如果不对他重新设置就是用,会出现未定义行为,一个++pos也是不行的
}
要是erase()能够返回下一个元素的位置,但是由于在关联容器中比较耗时,所以就没有这个特性,正确做法如下:

typedef std::map<std::string, float> StringFloatMap ;
StringFloatMap coll ;
StringFloatMap::iterator pos ;
for (pos = coll.begin(); pos != coll.end(); ++pos)
{
	if (pos->second == value)
		coll.erase(pos++) ;//pos会指向下一个元素,但返回指向原位置的一个副本,当调用erase时,pos已经不再指向即将被删除的元素了
	else
		++pos ;
}
这个好像有次面试遇到过

将map视为关联式数组,但其中有利有弊

利:方便,例如

std::map<std::sting, float> coll ;

coll["otto"] = 7.7 ;

如果没有键值为otto的元素,则首先调y用value的默认构造函数,然后将7.7赋值给value

弊:不小心插入一个元素,调用默认构造函数,然后重新赋值,这个速度比较慢

#include <iostream>
#include <map>
#include <string>
#include <iterator>
using namespace std;
int main()
{
	typedef map<string, float> StringFloatMap ;//设置排序规则从大到小
	StringFloatMap stocks ;
	stocks["A"] = 2.3 ;
	stocks["B"] = 2.4 ;
	stocks["C"] = 2.5 ;
	stocks["D"] = 2.6 ;
	StringFloatMap::iterator pos ;
	for (pos = stocks.begin(); pos != stocks.end(); ++pos)
	{
		cout <<"stock:"<< pos->first <<"\t"
			 << "price:" << pos->second <<endl ;
	}

	stocks["E"] = stocks["A"] ;//添加一个键值为E的元素
	stocks.erase("D") ;//删除键值为D的元素
	for (pos = stocks.begin(); pos != stocks.end(); ++pos)
	{
		cout << "stock:" << pos->first <<"\t"
			<< "price:" << pos->second <<endl ;
	}
	system("pause") ;
}
这里主要是应用了关联数组添加元素,erase删除元素

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值