一.Map

1.前言

  在程序中,经常会遇见关联的数据对出现,可以把这个数据对中的一个称作索引值,另外一个称作关联值或映射值,假如索引值是整数的时候,可以采用数组或者向量存储这些数据对,但是假如索引值是其他的任意数据类型的时候,就需要用到map 

2.使用map

#include <map>

map <string, string> addresses;

<1>添加元素

map中的第一个元素用于存放索引值,第二个元素用于存放映射值,为了对某一个索引值添加对应的映射元素,可以使用下标操作符,如对于上面定义的通信录addresses,要添加元素,可以如下:

      addresses["kfqcome"]="kfqcome@gmail.com"; 

   假如map中已经包含了某一键值(索引值),则后面对这一键值添加元素将不会起作用,即map中每个键值只可以对应于一个映射值,如:

      addresses["kfqcome"]="justin@gmail.com"; 

  这句代码将不会起作用

 

<2>查找

   要查找某个键值已经存在,可以使用find函数,有两种重载版本        

   iterator find(const key_type& k);

   const_iterator find(const key_type& k) const;

  对于上面的addressesmap对象,要查找键值为"kfqcome"的键值是否存在,可以使用如下的代码:

map<string,string>:: const_iterator iter=addresses.find(“kfqcome”);

   if (iter ==addresses.end())

      cout << "didn’t find" << endl;

   else

      cout << iter ->first << ''/t'' << iter ->second << endl;        

iter->first输出的数据对的键值,iter->second输出的数据对的对应的映射值

 

<3>取数据

  使用下标操作符加键值就可以取出对应的映射值

  map[key]

 

 

二.tuple

 

1.前言

  在c++中,相同函数名和相同参数的函数不能进行重载去返回不同类型的值,平常的做法定义两个名字相近的函数来达到这个目的。

  假设需要实现这样一个函数:将某个文件名转换为FILE * 文件描述符,函数名和参数都相同,只是返回类型不同

int convert_filename(const char* path);

FILE* convert_filename(const char* path); //出错

现在假如能够对这个函数包装需要返回的两种类型的数据,就可以十分方便的实现这个功能,tuple可以做到。

 

虽然说对于一些这样的问题可以自己定义一些结构体可以完成,但是tuple毕竟是已经开发完成的标准库,除了封装类型外还有许多其他的功能,在常规开发中可以节省许多时间,何乐而不为呢?

 

2.使用tuple

Tuple是一个大小固定的异构对象集合,即tuple可以包含任意类型的多个数据,目前标准的库支持0-10个元素的tuple,假如vs环境中没有安装到tuple库,可以自己下载boost库,它里面包含了tuple

 

<1>基本方法

使用tuple的例子:

#include "boost/tuple/tuple.hpp"

#include <string>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

boost::tuple<int,double,std::string>triple(42,3.14,"The amazing tuple!");

      int i=boost::tuples::get<0>(triple); //i=42

      double d=triple.get<1>(); //d=3.14

      std::string s=boost::get<2>(triple);

      return 0;

}

 

同时对于1中的那个文件名转换函数,可以将其写成:

typedef tuple<int, FILE *> file_t;

file_t convert_filename(const char* path);

 

 

<2>make_tuple函数

       可以使用make_tuple函数来创建tuple对象,如:

boost::tuple<int,double,std::string> t = boost::make_tuple(123,3.14159,"kk");

 

 

三.Multimap

       前面看到map对于一个键值只能存放一个与其对应的映射值,但是实际的应用中,经常会碰到一个键值对应多个映射值的情况,比如一个人可以有多个手机号码,或者有多个电子邮箱等。

 

<1> 构造函数

 

multimap<Key, Data, Compare, Alloc>

Key:键值的类型

Data:multimap的数据类型

Compare:键值的比较函数,函数使用两个参数,参数的类型就是键值的类型,如果第一个参数的值小于第二参数的值,则返回true,否则返回false

Alloc:内存分配器,用于内部的内存管理

 

<2> 添加和查询

       前面的map是采用下标操作符来添加和获取数据对,但是对于multimap,用下标操作符来添加数据对也许可以,但是用下标来获取则会出现问题,因为一个键值可以对应多个映射值,使用下标操作符取的话就难以去确定选择哪个映射值。基于这个原因,标准库设计者不采用下标来进行这些操作,而是设计另外的函数。

添加元素:insert,使用pair类型作为参数

multimap<string,string> dns;

   dns.insert(make_pair("192.168.1.19","www.kfqcome.com"));

   dns.insert(make_pair("192.168.1.19","kfqcome.com"));

   dns.insert(make_pair("192.168.1.19","www.kfqcome.org"));  

 

1)查询单个值

  find,使用键值作为参数

  find 函数定义

  iterator find(const key_type& k);

  const_iterator find(const key_type& k) const;

  find查询得到的迭代器指向这个键值与它的第一个映射值

使用举例:

   iter=dns.find("192.168.1.19");

   if(iter!=dns.end())

   {

      printf("has found/n");

   }

   else

   {

      printf("haven't found/n");

}

 

2)查询某键值对应的映射值的个数

       count,使用键值作为参数

       int num=dns.count("192.168.1.19");//num=3

 

3)查找某键值的下界和上界对应的元素

       某键值的下界是指multimap中与这个键值相等或者比这个键值大一级元素。

       某键值的上界是指multimap中比这个键值大一级的元素

multimap<string,string> dns;

   dns.insert(make_pair("192.168.1.19","www.kfqcome.com"));

   dns.insert(make_pair("192.168.1.19","kfqcome.com"));

   dns.insert(make_pair("192.168.1.15","www.kfqcome.info")); 

   dns.insert(make_pair("192.168.1.19","www.kfqcome.org"));  

   dns.insert(make_pair("192.168.1.1","www.vision.com"));

   typedef multimap<string,string>::iterator MIT;

   pair<MIT,MIT> range=dns.equal_range("192.168.1.1");

   MIT lowIter=range.first;

   MIT upperIter=range.second;

   cout<<"low range of key "<< lowIter->first<<":"<<lowIter->second<<endl;

   cout<<"upper range of key" <<upperIter->first<<":" << upperIter->second <<endl;

 

 

输出的结果为是:

low range of key 192.168.1.1:www.vision.com

upper range of key192.168.1.15:www.kfqcome.info 

注意:如果查找的键值已经是multimap最大的,那么它的上界会为空


使用这个可以获得有相同键值的所有映射值,如下:

multimap<int,string> courses;

   courses.insert(make_pair(1,"math"));

   courses.insert(make_pair(2,"computer science"));

   courses.insert(make_pair(2,"programming"));

   courses.insert(make_pair(4,"electronics"));

   courses.insert(make_pair(6,"biology"));

   typedef multimap<int,string>::iterator MIT;

   pair<MIT,MIT> range=courses.equal_range(2);

   MIT lowIter=range.first;

   MIT upperIter=range.second;

   MIT iter;

   for(iter=lowIter;iter!=upperIter;)

   {

      cout<<"key "<<iter->first<<": "<<iter->second<<endl;

      ++iter;

   }

 

 

 

输出的结果为:

key 2: computer science

key 2: programming

posted on 2011-06-18 07:29  柯大侠  阅读(3467)  评论(0编辑  收藏  举报