关联容器和顺序容器的本质区别:关联容器是通过键存取和读取元素、顺序容器通过元素在容器中的位置顺序存储和访问元素。因此,关联容器不提供front、push_front、pop_front、back、push_back以及pop_back,此外对于关联容器不能通过容器大小来定义,因为这样的话将无法知道键所对应的值什么。

两个基本的关联容器类型是map和set。map的元素以键-值对的形式组织:键用作元素在map的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。set和map类型的对象不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需使用multimap或mutiset类型,这两种类型允许多个元素拥有相同的键。

在介绍关联容器之前,必须先介绍一种与它相关的简单的标准库类型--pair类型:

pair类型的初始化-------在头文件utility中

pair<T1,T2> p1;                       创建一个pair对象,两个元素的类型分别是T1,T2类型,采用初值进行初始化

pair<T1,T2> p1(v1,v2);             创建一个pair对象,两个元素的类型分别是T1,T2类型,采用v1,v2分别进行初始化

make_pair(v1,v2);                     以v1、v2的只进创建一个pair对象,类型分别是v1、v2的类型

p.first                                      返回p中第一个公有数据成员

p.second                                 返回p中第二个公有数据成员

pair使用:

#include<utility>
pair<string,int> author("Peter",30);
cout<<author.first<<"\t"<<author.second<<endl;//可以直接访问数据成员

//使用typedef进行简化
typedef pair<string,string> Student;
Student s1,s2("aaa","bbb");
s1.first="ccc";
s1.second="ddd";

//使用make_pair函数生成一个新的pair对象
string first="eee",second="fff";
Student s3=make_pair(first,second);

map 关联数组,通过键来存储和读取

map 初始化:

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

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

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

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<<""<<map_it->second<<endl;

给map添加成员:

使用下标访问map对象:在map对象查找键值为x的元素如果找到则返回它的值(类型是map<k,v>::mapped_type),否则插入一个新的对象键值为x,值为map<k,v>中v的默      认初值。因此,使用下标访问map与使用下标访问数组或vector的行为不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。这一特性可以使程序简练:

map<string,int> word_count;
  word_count["Peter"]=10;//相当于增加一个键值对
  //创建一个map对象,用来记录每个单词出现的次数,十分简洁。

//因为如果读取的是一个新单词,则将在word_count中添加以该单词为索引的新元素
  map<string,int> word_count;
  string word;
  while(cin>>word)
  {
    ++word_count[word];
  }

使用Insert对map进行插入:

m .insert(e)                e是一个用在m上的value_type类型的值,如果e.first不在m中则插入一个值为.second的新元素,否则该键值在m中已经存在则保持不变,该

函数返回一个pair新类型,包含一个指向键值为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入该元素

m.insert(beg,end)       插入beg、end标记范围内的元素,如果该元素的m.first已经存在则不插入否则插入。返回void类型

m.insert(iter,e)           如果e.first不在m中,则创建新元素,并以迭代器iter为起点搜索新元素的存储位置,否则返回一个迭代器,指向m中具有的给定键的元素。

//用insert方法重写单词统计程序

map<string,int> word_count;
  word_count.insert(map<string,int>::value_type("aaa",1));
  map<string,int> word_count;
  string word;
  while(cin>>word)
 {
     pair<map<string,int>::iterator,bool> ret=word_count.insert(make_pair<string,int>(word,1));
    if(!ret.second)//如果没插入成功,证明原来已经存在键值,将统计值+1
  {
       ++ret.first->second;// first是一个迭代器,指向插入的键
   }
  }

查找和读取map中的元素:

m.count(k)                 返回k在m中出现的次数,在map中只是返回0、1

m.find(k)         如果k在m中的键值存在则返回相应的迭代器,否则返回超出来末端迭代器

//读取元素而又不插入新元素
    int occurs;
    map<string,int>::iterator it= word_count.find("foobar");//不存在,则返回end迭代器
   if(it!=word_count.end())//可能找不到
   {
    occurs=it.second;
   }

从map中删除元素 ,使用erase与顺序容器功能一样:

m.erase(k) 删除m中键为k的元素。返回值为被删除元素的个数,对于map容器而言,其值必然是0或1。

m.erase(p) 从m中删除迭代器p所指向的元素。返回值为void类型。

m.erase(b,e) 从m中删除一段由一对迭代器范围的元素。返回值为void类型。

map对象的迭代遍历:

map<string,int> word_count;

map<string,int>::const_iterator iter = word_count.begin();
      while(iter!=word_count.end())
       {
         cout<<iter->second<<endl;
         iter++;
      }

set类型

Set的作用就是排序。每个元素的值不能直接被改变。 它是一个容器,它用于储存数据并且能从一个数据集合中取出数据。它的每个元素的值必须惟一,而且系统会根据该值来自    动将数据排序。每个元素的值不能直接被改变。

大小可变的集合,支持通过键值实现的快速读取。对于单纯想知道一个值是否存在则set容器最适用

在set容器中value_type不是pair类型,而是与key_value的类型相同,它的键值类型也是唯一的且不能修改

在set也支持find、count、insert、erase操作

在set中添加元素:;

set<int> set1;
    pair<set<int>::iterator,bool> p=set1.insert(1);//返回pair类型对象,包含一个迭代器和一个布尔值
   set1.insert(2);
   int arr[]={1,2,3};
   set<int> set2;
   set2.insert(arr,arr+3);//返回void类型

从set中获取元素:与map方法使用类似,使用find和count函数。

C++之容器(关联容器)的更多相关文章

  1. [C++ Primer] : 第11章: 关联容器

    目录 使用关联容器 关联容器概述 关联容器操作 无序容器 使用关联容器 关联容器与顺序容器有着根本的不同: 关联容器中的元素是按关键字来保存和访问的, 按顺序容器中的元素是按它们在容器中的位置来顺序保 ...

  2. C++基础之关联容器

    关联容器 关联容器和顺序容器的本质区别:关联容器是通过键存取和读取元素.顺序容器通过元素在容器中的位置顺序存储和访问元素.因此,关联容器不提供front.push_front.pop_front.ba ...

  3. STL之关联容器

    关联容器包含map.set.multimap.multiset. 关联容器的特点是明显的,相对于顺序容器,有如下特点: 1.其内部是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的. 2.se ...

  4. STL_关联容器 VS C++ hashmap

    红黑树和哈希表区别: http://m.blog.csdn.net/article/details?id=52133283 关于STL中关联容器的几个问题: (1)为何map和set的插入删除效率比用 ...

  5. C++学习基础四——顺序容器和关联容器

    —顺序容器:vector,list,queue1.顺序容器的常见用法: #include <vector> #include <list> #include <queue ...

  6. C++ 关联容器

    <C++ Primer 4th>读书笔记 关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素. 关联容器(Ass ...

  7. C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作

    关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名  key_type    此容器类型的关键字类型 mapped_type  每个关键字关联的类型, ...

  8. C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型

    标准库定义了两种主要的关联容器:map和set map中的元素时一些关键字-值(key-value)对,关键字起到索引的作用,值则表示与索引相关的数据.set中每个元素只包含一个关键字,可以完成高效的 ...

  9. 使用multimap创建重复键关联容器

    在“使用 <map> 库创建关联容器”一文中,我们讨论了标准库中的 map 关联容器.但那只是 map 容器的一部分.标准库还定义了一个 multimap 容器,它与 map 类似,所不同 ...

  10. Chapter11:关联容器

    当用decltype来获得一个函数指针类型时,必须加上一个*来指出我们要使用一个给定函数类型的指针.decltype<CompareIsbn>*. map<string, int&g ...

随机推荐

  1. 【python】用 sqlacodegen 将存在的数据库表 转化成model.py

    Flask的sqlalchemy对数据库表的模型提供了很多易用的方法.为了使用这些内容,需要将数据库表按照Flask识别的格式创建成Model,但是一般我们都是在已经创建好的数据库环境中开发Pytho ...

  2. javascript中var let const三种变量声明方式

    javascript中var let const三种变量声明方式 1.var  ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...

  3. hadoop 编码实现文件传输、查看等基本文件控制

    hadoop集群搭建参考:https://www.cnblogs.com/asker009/p/9126354.html 1.创建一个maven工程,添加依赖 <?xml version=&qu ...

  4. [洛谷P2106]Sam数

    题目大意:问长度为$n$的$Sam$数有几个,$Sam$数的定义为没有前导零,相邻两个数字之差绝对值小于等于$2$的数 题解:发现转移方程一定,可以矩阵快速幂. 卡点:没有特判$n=1$的情况 C++ ...

  5. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下… 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么 ...

  6. Android Fragment 使用详解

    虽然网上有很多关于Fragment的文章,但我这里还是要写这篇笔记,因为我在编写程序的过程中发现了一个问题,至今未解决,希望得到大家的帮助: PS:当我在Fragment中定义一个名为setIndex ...

  7. [Leetcode] valid sudoku 有效数独

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  8. 实验三 Java敏捷开发与XP实践

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计                         班级:1353            姓名:陈巧然     ...

  9. ES6箭头函数总结

    1. 箭头函数基本形式 let func = (num) => num; let func = () => num; let sum = (num1,num2) => num1 + ...

  10. shell运用

    在shell脚本一 中,我讨论了shell脚本的语法规范,shell脚本的变量,以及shell脚本的测试语句. 仅仅懂得这些只能写简单的脚本,在简单的脚本中各条语句按顺序执行,从而实现自动化的管理,顺 ...