关联容器知识点通关

2023-05-16

关联容器

  • 1.关联容器与顺序容器的区分
  • 2.关联容器的数据
    • 2.1 数据存储
      • 2.1.1 pair类型
      • 2.1.2 关联容器的类型别名
      • 2.1.3 关联容器迭代器
    • 2.2 关联容器的初始化
  • 3. 关联容器的增删改查
    • 3.1 关联容器增加元素
    • 3.2 删除关联容器的元素
    • 3.3 修改map的元素
    • 3.3 查找关联容器的元素
  • 4. 关联容器使用示例

1.关联容器与顺序容器的区分

顺序容器,顾名思义就是其存储时是按照“位置顺序”来进行存储的,这里的顺序的含义就是我们常常理解的编号。以我们常用的vectorstring为例,其每个元素都是按照编号来进行存储的,而且我们在顺序容器上的操作一般也是基于这些位置(编号)的遍历来实现的。与顺序容器不同的是,关联容器的设计原因就是为了实现“高效按值访问”,所以关联容器的数据存储核心一般都是“关键字”。关联二字的应有之义就是关键字和值建立关联关系

另外,对于顺序容器而言,其底层存储结构是数组或者链表这种线性数据结构,而关联容器一般是由红黑树、哈希表等来实现的。所以顺序容器一般是基于位置处理,关联容器是基于关键字进行处理。

我们不能简单的将顺序顺序和关联容器的区分理解为是否有序;关联容器并不代表就是无序的,基于红黑树实现的关联容器都是有序的,只有基于哈希表实现的unordered_map和unordered_set才是无序的。

2.关联容器的数据

2.1 数据存储

2.1.1 pair类型

关联容器的数据存储一般是采用键值对的形式。也就是我们常常见到的key-value;我们在第一部分提到过,关联容器的访问是根据key值进行访问的,关联二字的含义也是key与value建立的关联关系。所以很有必要以一种数据类型来表达这个键值对。C++中提供了标准库类型pair来表示一对数据,它定义于头文件utility中。对于一个pair数据来说,有以下几种方式进行定义。

	pair<string,string> anon;
	pair<string,int> p("hello",1);
	pair<int,string> p1 = {1,"world"};
	make_pair("hello","world");

我们可以使用firstsecond来访问其键和值两个数据成员。

	cout<<p.first;	//输出hello
	cout<<p.second;	//输出1

2.1.2 关联容器的类型别名

在使用关联容器时,除了可以使用根前面的顺序容器相同的一些类型别名之外(如iterator,size_type,value_type,reference),还有一些自己特殊的类型别名总结如下:

表1 关联容器特有的类型别名
名称含义
key_type容器的关键字类型
mapped_value容器的关键字的关联类型
value_type对于set,是于key_type相同;对于map,是一个pair类型,<key_type,mapped_type>

2.1.3 关联容器迭代器

关联容器的迭代器使用与顺序容器的迭代器使用是相同的。但是对于解引用之后的操作要看其是否是一个pair类型,如果是map的话,对迭代器解引用就是一个pair,需要使用firstsecond来进行键值访问。

对于set和map而言,如果用迭代器进行访问的话,是不能通过迭代器来进行修改key值的。我们可以理解为:对于set,迭代器必然是const_iterator;对于map,虽然迭代器可能为简单的iterator,但是还是不能通过迭代器修改关键字成员的值。

2.2 关联容器的初始化

不能说与顺序容器的十分相似,只能说初始化一模一样。

3. 关联容器的增删改查

对于增删改查来说,方法还是那么些方法。只是在使用时可能要根据set和map的特性注意一下。下面只介绍特殊性。

3.1 关联容器增加元素

基于关联容器的特性,肯定是不能使用push_backpush_front这种方法。但是,关联容器的添加元素还是一样可是使用普通的insert方法和emplace方法。使用方法类似。

	//定义一个保存数据的vector
	vector<int> ivec = {2, 4, 6, 7, 2, 4, 6, 7};
    map<string,size_t> wordCount;
    set<int> s;
    // 给set插入元素
    //使用范围迭代器插入
    s.insert(ivec.cbegin(),ivec.cend());
    // 给map插入元素
    wordCount.insert({"wow",1});

使用虽然相同,但是在进行数据插入时,我们要区分好关联容器是否允许元素重复。对于set等不允许重复关键字的关联容器而言,如果插入一个已有的键,那么就会直接忽略这个操作。而对于multiset等允许重复的关联容器而言,就会继续执行插入。

除了使用上面的函数进行元素添加,我们通常更习惯使用下标来添加元素,示例如下:

	//当从输入流输入一个string,就建立一个以此string为关键字的元素
	while(cin>>word){
        ++word_count[word];
    }

3.2 删除关联容器的元素

同前面一样,由于使用的是根据关键字访问,所以pop_back、pop_back方法是不能再使用的。我们使用erase方法来进行关联容器的数据删除。此时的erase特性如下

表2 关联容器的数据删除操作
方法形式使用细节
erase(k)删除容器中关键字为k的元素,返回值为size_t表示删除元素的数量
erase§删除迭代器p指定的元素,其中p必须真实指向一个容器元素,返回p之后元素的迭代器
erase(p,e)删除[p,e)范围内的元素,返回e
 map<int,string> ma = {{1,"hello"},{2,"world"},
        {3,"nihao"},{4,"shijie"}
    };
    //删除关键字为2的值,返回值为删除元素的数量
    cout<<"删除的元素个数为:"<<ma.erase(2)<<endl;

3.3 修改map的元素

关联容器的键不能修改,但是其值却是可以修改的,虽然关联容器某种程度上而言并不是根据位置序号访问,但它可以用特殊的下标——进行访问元素。使用形式与顺序容器一样,可以通过at函数或者[]来实现。

	//访问map的元素
    cout<<"ma[1] is :"<<ma[1]<<endl;
    cout<<"ma[1] is :"<<ma.at(1)<<endl;
    //map的下标运算符获得的对象与解引用map迭代器后的对象是不同的
    //是一个mapped_type
    auto m =ma[1];

使用map的下标操作还可以进行元素的添加,如果使用一个不在容器中的关键字作为下标,就会添加一个具有此关键字的元素到map中。这也就造成在顺序容器和关联容器使用下标访问时返回值是不一样的,前者是元素类型本身,后者则是一个对应的mapped_value.

3.3 查找关联容器的元素

在关联容器中使用的查找元素的方法一般有以下两种

表3 关联容器的数据查找操作
方法形式使用细节
find(k)查找关键字为k的元素是否存在,若存在返回指向第一个关键字为k的元素的迭代器,否则返回尾后迭代器end
count(k)返回容器中关键字为k的元素数量;注意若是不允许重复的容器,方法就类似于find函数。

4. 关联容器使用示例

下面的例子是基于C++primer第五版中的单词转换程序的实现。

#include<iostream>
#include<fstream>
#include<sstream>
#include<map>
#include<stdexcept>
using std::ifstream;using std::endl;
using std::cout;using std::cin;
using std::string;using std::map;
using std::runtime_error;
using std::istringstream;

//根据映射文件建立单词映射map
map<string,string> buildMap(ifstream& mapfile){
    map<string,string> w_map;
    string key;
    string value;
    //注意getline的读取包含空格
    while(mapfile>>key && getline(mapfile,value)){
        if(value.size()<1){
            throw runtime_error("no similiar rule\n");
        }
        //  w_map[key] = value.substr(1);
        w_map.insert({key,value.substr(1)});
    }
    return w_map;
}
//单个单词的转换
const string &transform(const string &s,const map<string,string> &m){
    auto mp = m.find(s);
    //若存在映射则转换
    // 否则输出本身
    if(mp != m.end()){
        return mp->second;
    }
    else return s;
}
// 读取文件并转换
void wordTransform(ifstream& mapFile,ifstream& input){
    map<string,string> w_map = buildMap(mapFile);
    //保存输入的一行
    string text;
    while(getline(input,text)){
        istringstream strin(text);
        string word;
        //第一个单词的话前面没有空格
        bool first = true;
        while(strin>>word){
            if(first){
                first =false;
            }else cout<<" ";
            cout<<transform(word,w_map);    
        }
        cout<<endl;
    }
}

int main(){
    ifstream mapfile("./STL_associative/rule.txt");
    if(!mapfile){
        throw runtime_error("no rules file");
    }
    ifstream input("./STL_associative/tran.txt");
    if(!input){
        throw runtime_error("no trans file");
    }
    wordTransform(mapfile,input);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关联容器知识点通关 的相关文章

  • java统计文本中某个字符串出现的次数

    原文 xff1a java统计文本中某个字符串出现的次数源代码下载地址 xff1a http www zuidaima com share 1550463297014784 htm 统计文本中某个字符串出现的次数或字符串中指定元素出现的次数
  • GitHub上最火的Android开源项目

    摘要 xff1a 截至目前 xff0c 在GitHub 最受欢迎的开源项目 系列文章中我们已介绍了40个Android开源项目 xff0c 对于如此众多的项目 xff0c 你是Mark 和码友分享经验还是慨叹 活到老要学到老 xff1f 今
  • Android 自定义类库打包jar! 谁说不可以打包res 文件?

    我们经常会有这种需求 xff0c 自己开发一个类库jar包 xff0c 提供给别人调用 网上很多教程都是这么说 xff1a 创建一个Android project 用eclipse 的export 导出 xff0c 去掉AndroidMan
  • Android WebView开发问题及优化汇总

    我们在native与网页相结合开发的过程中 xff0c 难免会遇到关于WebView一些共通的问题 就我目前开发过程中遇到的问题以及最后得到的优化方案都将在这里列举出来 有些是老生常谈 xff0c 有些则是个人摸索得出解决方法 下面就是整理
  • malloc()和free()注意点

    1 调用free 释放内存后 xff0c 不能再去访问被释放的内存空间 该段内存被释放后 xff0c 很有可能该指针仍然指向该内存单元 xff0c 但这块内存已经不属于原来的应用程序 xff0c 此时的指针为悬挂指针 xff08 可以赋为N
  • 杰克逊

    一 个人资料 迈克尔 约瑟夫 杰克逊 xff08 Michael Jackson xff09 全 名 xff1a Michael Joseph Jackson 中译名 xff1a 迈克尔 约瑟夫 杰克逊 其他译名 xff1a 台湾译名 xf
  • 搜索引擎语法汇总

    通过搜索引擎来查找自己想要的网址或信息是最快捷的方法 xff0c 也是最佳途径 因此 xff0c 掌握基本的搜索语法及使用方法对每个冲浪者是十分重要的 搜索引擎一般是通过搜索关键词来完成自己的搜索过程 xff0c 即填入一些简单的关键词来查
  • 用C#编写的银行取款系统

    using System using System Collections Generic using System Linq using System Text namespace Inten class Data st S 61 new
  • Oracle收购Sun并不总是坏事的8大原因

    关于Oracle为什么要收购Sun已经谈论了很久 xff0c 人们不禁会问 xff0c 自由世界真会消亡 xff0c 同时产生一个垄断的数据库世界吗 xff1f 虽然回答的语气可能有点肯定 xff0c 但我们也应该记住 xff0c 这起收购
  • 构造函数为什么不能为虚函数

    虚函数采用一种虚调用的方法 虚调用是一种可以在只有部分信息的情况下工作的机制 xff0c 特别允许我们调用一个只知道接口而不知道其准确对象类型的函数 但是如果要创建一个对象 xff0c 则必须要知道对象的准确类型 xff0c 因此构造函数不
  • Linux下切换Python版本的几种方法

    Linux下切换Python版本的几种方法 参考链接 xff1a 1 https www cnblogs com feynxd p 11367806 html 2 https blog csdn net weixin 34355559 ar
  • 基于ip的手机地理定位

    现在lbs服务比较火 xff0c 基本上都需要定位用户的地理信息 xff0c 用户地理信息一般是通过gps来定位实现的 xff0c 那么假如 用户的gps坏了 xff0c 或者没有开启 xff0c 那么怎么获得用户的地理信息的呢 xff1f
  • lm3s811 学习笔记(二)【自己建工程】

    在lm3s811 学习笔记 一 里 xff0c 我讲述了如何使用别人的工程 xff0c 烧写程序到板子上 这一节我来讲讲自己是怎么创建工程 不过用的还是别人的程序 xff0c 毕竟自己对lm3d811驱动库还不熟悉 打开keil 4 1 在
  • 计算机文化基础

    计算机应用基础试题 一 填空题 每空1分 xff0c 共30分 1 计算计的软件系统通常分成 软件和 软件 2 字长是计算机 次能处理的 进制位数 3 1KB 61 B xff1b 1MB 61 KB 4 计算机中 xff0c 中央处理器C
  • 74ls系列中文资料功能介绍

    型号 功能 74ls00 2输入四与非门 74ls01 2输入四与非门 oc 74ls02 2输入四或非门 74ls03 2输入四与非门 oc 74ls04 六倒相器 74ls05 六倒相器 oc 74ls06 六高压输出反相缓冲器 驱动器
  • qt学习笔记(二)之布局管理器&信号与槽(简介)

    我们在上节的程序中加点小应用 主要是用到了布局管理器和信号与槽 在这里我也只是简单介绍一下 随着后续的深入研究 xff0c 接下来会具体介绍 一 布局管理器 include lt QtGui gt int main int argc cha
  • Android 开发之 Activity BroadcastReceiver Service和音乐播放

    Activity的生命周期 xff1a Activity有三个状态 xff1a 当它在屏幕前台时 位于当前任务堆栈的顶部 xff0c 它是激活或运行状态 它就是响应用户操作的Activity 当它失去焦点但仍然对用户可见时 xff0c 它处
  • JSON-lib框架,转换JSON、XML不再困难

    Json lib可以将Java对象转成json格式的字符串 xff0c 也可以将Java对象转换成xml格式的文档 xff0c 同样可以将json字符串转换成Java对象或是将xml字符串转换成Java对象 一 准备工作 1 首先要去官方下
  • xStream完美转换XML、JSON

    xStream框架 xStream可以轻易的将Java对象和xml文档相互转换 xff0c 而且可以修改某个特定的属性和节点名称 xff0c 而且也支持json的转换 xff1b 前面有介绍过json lib这个框架 xff0c 在线博文
  • C++程序员经常问的11个问题

    C 43 43 程序员经常问的11个问题 这篇文章收了好长时间 xff0c 但还是觉得贴出来 xff0c 作为收藏 xff0c 在网上这样的浮躁环境 xff0c 很少能认认真真地看这样长的文章 xff0c 有时间我也要把 Effective

随机推荐

  • C++监控USB设备

    这个程序前阵子帮一个朋友实现的 xff0c 之前从未用消息队列做过类似的事情 xff0c 做完后感觉其在线程同步 xff0c 通信发面很好用 xff0c 难怪COM也用这套机制 程序稍微修改便能用作一般性的处理 xff0c 目前实现的功能类
  • TCP通信

    客户端的代码 xff1a 1 include 34 utili h 34 2 3 int main 4 5 int sockCli 61 socket AF INET SOCK STREAM 0 6 if sockCli 61 61 1 7
  • 解决引用openssl静态库libcrypto.a和libssl.a出现undefined reference to错误的问题

    解决引用openssl静态库libcrypto a和libssl a出现undefined reference to错误的问题 最近在做使用openssl链接http和https的项目 xff0c 编译时出现以下问题 usr local o
  • ssh允许root登录

    vi etc ssh sshd config Authentication LoginGraceTime 120 PermitRootLogin without password 找到这里 xff0c 把它注释 PermitRootLogi
  • 大型网站技术架构

    大型网站技术架构 xff08 1 xff09 网站都是从小网站一步一步发展为大型网站的 xff0c 而这之中的挑战主要来自于庞大的用户 安全环境恶劣 高并发的访问和海量的数据 xff0c 任何简单的业务处理 xff0c 一旦需要处理数以 P
  • iOS线程池

    多线程开发是一件需要特别精心的事情 xff0c 即使是对有多年开发经验的工程师来说 为了能让初级开发工程师也能使用多线程 xff0c 同时还要简化复杂性 各种编程工具提供了各自的办法 对于iOS来说 xff0c 建议在尽可能的情况下避免直接
  • QT https post请求

    以VS开发为例 因为https访问需要用到SSL认证 xff0c 而QT默认是不支持SSL认证 xff0c 所以在使用之前必须先做一些准备工作 xff1a 需要安装OpenSSL库 xff1a 1 首先打开http slproweb com
  • 在windows下的QT编程中的_TCHAR与QString之间的转换

    由于在windows下的QT编程中 xff0c 如果涉及到使用微软的API xff0c 那么不可避免使用 TCHAR这些类型 xff0c 因此在网上查了一下 xff0c 其中一个老外的论坛有人给出了这个转换 xff0c 因此在这里做一下笔记
  • QT图片旋转

    目前发现有两种方法 xff0c 如下 xff1a 1 使用QPixmap的transformed函数旋转 xff0c 这个函数默认是以图片中心为旋转点 xff0c 不能随意设置旋转点 xff0c 使用如下 xff1a QMatrix lef
  • signtool对EXE进行签名

    数字证书 xff0c 真是个神奇的东西 xff0c 可以保证软件不被修改 xff0c 可以表明文件的发布日期 xff0c 最重要的 xff0c 可以很大程度的减少杀毒软件的误报 xff0c 当然 xff0c 这就要使用可信任的机构颁发的证书
  • Linux C语言实现UDP的发送和接收

    发送端实现 xff1a U1 c include lt stdio h gt include lt stdlib h gt include lt string h gt include lt sys socket h gt include
  • C语言 特殊的数字

    问题描述 153是一个非常特殊的数 xff0c 它等于它的每位数字的立方和 xff0c 即153 61 111 43 555 43 333 编程求所有满足这种条件的三位十进制数 span class token macro property
  • STL简单的介绍

    我们要知道C 43 43 的含义 xff1a C语言 43 类 43 模板 xff08 STL就是典型的代表 xff09 STL是Standard Template Library的简称 xff0c 中文名是标准模库 从根本上说 xff0c
  • C语言 查找整数

    问题描述 给出一个包含n个整数的数列 xff0c 问整数a在数列中的第一次出现是第几个 输入格式 第一行包含一个整数n 第二行包含n个非负整数 xff0c 为给定的数列 xff0c 数列中的每个数都不大于10000 第三行包含一个整数a x
  • C语言 字母图形

    问题描述 利用字母可以组成一些美丽的图形 xff0c 下面给出了一个例子 xff1a ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形 xff0c 请找出这个图形的规律 xff0c 并输
  • C++ 无参构造函数

    设计表示平面坐标位置的点类 xff0c 可以修改和获取点的x y坐标值 xff0c 设置构造函数对点的数据成员进行初始化 xff0c 并且能够用数组保存一系列的点 span class token macro property span c
  • C语言 矩阵乘法

    问题描述 给定一个N阶矩阵A xff0c 输出A的M次幂 xff08 M是非负整数 xff09 例如 xff1a A 61 1 2 3 4 A的2次幂 7 10 15 22 输入格式 第一行是一个正整数N M xff08 1 lt 61 N
  • C语言 分解质因数

    问题描述 求出区间 a b 中所有整数的质因数分解 输入格式 输入两个整数a xff0c b 输出格式 每行输出一个数的分解 xff0c 形如k 61 a1a2a3 a1 lt 61 a2 lt 61 a3 xff0c k也是从小到大的 具
  • 编译原理 赋值语句翻译成四元式

    赋值语句及算数表达式的翻译 将赋值语句翻译成四元式的语义描述 1 S gt id 61 A 2 A gt id 3 A gt int 4 A gt real 5 A gt A1 43 A2 6 A gt A1A2 7 A gt A1 8 A
  • 关联容器知识点通关

    关联容器 1 关联容器与顺序容器的区分2 关联容器的数据2 1 数据存储2 1 1 pair类型2 1 2 关联容器的类型别名2 1 3 关联容器迭代器 2 2 关联容器的初始化 3 关联容器的增删改查3 1 关联容器增加元素3 2 删除关