C++9.3.7 容器删除元素--erase、clear、pop_front函数

简介

看一下9.5节容器之间的区别—-list类似于链表,容易增删改,queue是两端增删改容易。,所以删除时,用到最多的容器时list

1.删除第一个或最后一个元素—–pop_front 和pop_back 函数,函数返回void
2.删除容器内的一个或一段元素—–erase函数,erase都返回一个迭代器,它指向被删除的元素后面的元素
3.删除容器内所有的元素—clear函数
4. 注意:在删除元素后迭代器会失效,因此一定要对迭代器重新赋值。另外,erase函数返回一个迭代器,指向被删除元素的下一个元素。因为在for语句头中要对迭代器加1,所以在if语句中将迭代器减1,以免漏掉需要处理的元素。

===========================================================================================================

一、删除元素—–queue和list容器

前面提到过使用insert操作在容器的任何位置插入元素,并支持特定的push_back和push_front 操作在容器首部或尾部插入新元素。
类似的,容器提供了erase操作和特定的pop_front和pop_back操作来删除容器内的元素。

这里写图片描述

1. 删除第一个或最后一个元素pop_front 和pop_back 函数—list可以,queue也可以

  • pop_front 和pop_back函数用于删除容器内的第一个和最后一个元素。但vector容器类型不支持pop_front操作。这些操作删除指定的元素并返回void;

  • pop_front 经常与front操作配套使用,实现以栈的方式处理容器

  • pop_front 和pop_back函数的返回值并不是删除的元素值,而是void。要获取删除的元素值,则必须在删除元素之前调用front或back函数。

while(!ilist.empty()){
   process(ilist.front());//获取要删除的元素
   ilist.pop_front();//删除第一个元素

}

2.删除容器内的一个或一段元素erase操作—list容器

  • 删除一个或一段元素更通用的方法是erase操作。

  • 该操作有两个版本:删除由一个迭代器指向的单个元素,删除由一对迭代器标记的一段元素。erase的这两种形式都返回一个迭代器,它指向被删除的元素后面的元素。

  • 必须确保用作参数的迭代器或迭代器范围是有效的。

  • * 通常要在容器中找到要删除的元素后,才使用erase操作。寻找一个指定元素的最简单方法是使用标准库的find算法。*

  • find算法在后面的11.1节还会介绍,为了使用find函数或其他泛型算法,在编程时,必须将algorithm头文件包含进来。

  • find函数需要一对标记查找范围的迭代器以及一个在该范围内查找的值做参数,查找完成后,该函数返回一个迭代器,它指向具有指定值的第一个元素,或超出末端的下一个位置。

string searchValue("Quasimodo");//定义一个string对象
list<string>::iterator iter=find(slist.begin(),slist.end(),searchValue);
if(iter!=slist.end())
    slist.erase(iter);//是iter,不是*iter
//注意:在删除元素之前,必须确保迭代器是不是end迭代器。使用erase操作删除单个元素必须确保该元素确实存在------如果删除指向超出末端的下一个位置的迭代器,那么erase操作的行为未定义

3.删除容器内所有的元素—clear函数

slist.clear();//删除所有元素
slist.erase(slist.begin(),slist.end());同上

//erase 函数的迭代器对版本提供了删除一部分元素的功能:
list<string>::iterator elem1,elem2;
elem1=find(slist.begin(),slist.end(),val1);//elem1指向val1
elem2=find(elem1,slist.end(),val2);//elem2指向val2
slist.erase(elem1,elem2);//删除elem1到elem2之间的所有元素,但不包括elem2指向的元素
  • erase、pop_front、pop_back函数使指向被删除元素的所有迭代器失效。对于vector容器,指向删除点后面的元素的迭代器通常也会失效,而对于queue容器,如果删除时不包括第一个元素或最后一个元素,那么deque容器相关的所有迭代器都会失效
//习题9.25
//需要删除一段元素时,如果val1和val2相等,那么程序会怎样?其中一个不存在,程序会怎样?

//解答
//相等,那么不会删除任何元素。
//其中一个不存在,或两个都不存在,则会发生运行错误。
//习题9.26

#include <iostream>
#include<string>
#include<cctype>
#include<vector>
#include<list>

using namespace std;
int main()
{

int ia[]={0,1,1,2,3,4,5,8,13,21,55,89};
vector<int> ivec(ia,ia+11);
list<int> ilst(ia,ia+11);

for(list<int>::iterator lit=ilst.begin();lit!=ilst.end();lit++){

if(*lit%2!=0)
{
    lit=ilst.erase(lit);//删除元素
    --lit;
}
cout<<*lit;
}

cout<<endl;
for(vector<int>::iterator vit=ivec.begin();vit!=ivec.end();vit++){

if(*vit%2==0)
{
    vit=ivec.erase(vit);//删除元素
    --vit;//迭代器重新赋值,进行回退,指向被删除元素的前一个元素。
}
cout<<*vit;
}

    return 0;
}

注意:在删除元素后迭代器会失效,因此一定要对迭代器重新赋值。另外,erase函数返回一个迭代器,指向被删除元素的下一个元素。因为在for语句头中要对迭代器加1,所以在if语句中将迭代器减1,以免漏掉需要处理的元素。

  • 9
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 介绍 7 1.1 受众 7 1.2 标准参考规范 7 1.3 术语及定义 9 1.4 缩写和符号 12 2 系统架构 15 3 卡片架构 16 3.1 安全域 16 3.2 全局服务应用 17 3.3 运行时环境 17 3.4 可信任框架 17 3.5 GlobalPlatform环境(OPEN) 17 3.6 GlobalPlatform API 17 3.7 卡片内容 17 3.8 卡片管理器 18 4 安全架构 19 4.1 目标 19 4.2 安全职责和要求 19 4.2.1 发卡方的职责 19 4.2.2 应用提供方的职责 19 4.2.3 授权管理者的职责 20 4.2.4 卡片组件的安全性要求 20 4.2.4.1 运行时环境的安全性要求 20 4.2.4.2 可信任框架的安全性要求 20 4.2.4.3 OPEN的安全性要求 20 4.2.4.4 安全域的的安全性要求 20 4.2.4.5 全局服务应用的安全性要求 21 4.2.4.6 应用的安全性要求 21 4.2.5 后台系统的安全性要求 21 4.3 加密支持 21 4.3.1 安全的卡片内容管理 21 4.3.1.1 加载文件数据块散列值 21 4.3.1.2 加载文件数据块签名(DAP) 22 4.3.1.3 委托管理令牌 22 4.3.1.4 收条 22 4.3.2 安全通信 22 5 生命周期模型 24 5.1 卡片生命周期 24 5.1.1 卡片生命周期状态 24 5.1.1.1 卡片生命周期状态 OP_READY 24 5.1.1.2 卡片生命周期状态 INITIALIZED 25 5.1.1.3 卡片生命周期状态 SECURED 25 5.1.1.4 卡片生命周期状态 CARD_LOCKED 25 5.1.1.5 卡片生命周期状态 TERMINATED 25 5.1.2 卡片生命周期状态的迁移 25 5.2 可执行加载文件和可执行模块生命周期 26 5.2.1 可执行加载文件生命周期 26 5.2.1.1 Executable Load Life Cycle LOADED 26 5.2.1.2 可执行加载文件的删除 27 5.2.2 可执行模块的生命周期 27 5.3 应用和安全域的生命周期 27 5.3.1 应用生命周期状态 27 5.3.1.1 应用生命周期状态 INSTALLED 27 5.3.1.2 应用生命周期状态 SELECTABLE 27 5.3.1.3 应用生命周期状态 LOCKED 28 5.3.1.4 应用的删除 28 5.3.1.5 应用自定义的生命周期状态 28 5.3.1.6 应用生命周期状态的迁移 28 5.3.2 安全域生命周期状态 29 5.3.2.1 安全域生命周期状态 INSTALLED 29 5.3.2.2 安全域生命周期状态 SELECTABLE 30 5.3.2.3 安全域生命周期状态 PERSONALIZED 30 5.3.2.4 安全域生命周期状态 LOCKED 30 5.3.2.5 安全域的删除 30 5.3.2.6 安全域生命周期状态的迁移 30 5.4 生命周期图解 31 6 GlobalPlatform环境(OPEN) 33 6.1 综述 33 6.2 OPEN服务 34 6.3 命令分发 34 6.4 逻辑通道和应用选择 34 6.4.1 隐式选择的分派 34 6.4.2 基本逻辑通道 35 6.4.2.1 基本逻辑通道的应用选择 35 6.4.2.1.1 基本逻辑通道上应用的隐式选择 35 6.4.2.1.2 基本逻辑通道上应用的显式选择 35 6.4.2.2 基本逻辑通道上的逻辑通道管理 36 6.4.2.3 基本逻辑通道上的应用命令分发 37 6.4.3 补充逻辑通道 37 6.4.3.1 补充逻辑通道的应用选择 37 6.4.3.1.1 补充逻辑通道上应用的隐式选择 37 6.4.3.1.2 补充逻辑通道上应用的显式选择 37 6.4.3.2 补充逻辑通道上的逻辑通道管理 38 6.4.3.3 补充逻辑通道上的应用命令分发 38 6.5 GlobalPlatform注册表 38 6.5.1 应用/可执行加载文件/可执行模块等数据元素 39 6.5.1.1 应用/可执行加载文件/可执行模块的AID 39 6.5.1.2 应用/可执行加载文件/可执行模块的生命周期 39 6.5.1.3 内存资源管理参数 39 6.5.1.4 权限 39 6.5.1.5 隐式应用选择参数 39 6.5.1.6 关联安全域的AID 39 6.5.1.7 应用提供方ID 39 6.5.1.8 服务参数 40 6.5.2 卡片级数据 40 6.6 权限 40 6.6.1 权限定义 40 6.6.2 权限分配 41 6.6.3 权限管理 42 6.7 GlobalPlatform可信任框架 42 7 安全域 44 7.1 概要描述 44 7.1.1 发卡方安全域 44 7.2 关联到安全域 44 7.3 安全域服务 45 7.3.1 应用对安全域服务的访问 45 7.3.2 安全域对应用的访问 46 7.3.3 个人化支持 46 7.3.4 运行时消息的支持 47 7.4 安全域数据 48 7.4.1 发卡方安全域 48 7.4.1.1 发卡方标识编号 48 7.4.1.2卡片映像编号 48 7.4.1.3 卡片标识数据 49 7.4.2 补充安全域 49 7.4.2.1 安全域提供方标识编号 49 7.4.2.2 安全域映像编号 49 7.4.2.3 安全域管理数据 49 7.5 安全域密钥 49 7.5.1 密钥信息 50 7.5.2 密钥访问条件 50 7.6 数据和密钥管理 51 8 全局平台服务 52 8.1 全局服务应用 52 8.1.1 注册全局服务 52 8.1.2 应用对全局服务的访问 52 8.1.3 全局服务参数 53 8.2 持卡方验证方法(CVM)应用 53 8.2.1 应用对CVM服务的访问 53 8.2.2 CVM管理 54 8.2.2.1 注册CVM 54 8.2.2.2 CVM状态 54 8.2.2.2.1 CVM状态ACTIVE 54 8.2.2.2.2 CVM状态INVALID_SUBMISSION 54 8.2.2.2.3 CVM状态VALIDATED 54 8.2.2.2.4 CVM状态BLOCKED 55 8.2.2.3 CVM格式 55 9 卡片和应用的管理 56 9.1 卡片内容管理 56 9.1.1 概述 56 9.1.2 对OPEN的要求 56 9.1.3 对安全域的要求 56 9.1.3.1 具备“令牌验证权限”的安全域 56 9.1.3.2 具备“授权管理权限”的安全域 56 9.1.3.3 具备“委托管理权限”的安全域 56 9.1.3.4 具备“全局删除权限”的安全域 57 9.1.3.5 具备“全局锁定权限”的安全域 57 9.1.3.6 具备“收条创建权限”的安全域 57 9.2 卡片内容的授权和管理 57 9.2.1 数据鉴别(DAP)模式验证 57 9.2.2 加载文件数据块的散列值 57 9.2.3 令牌 58 9.3 卡片内容的加载、安装和可选择化 58 9.3.1 概述 58 9.3.2 卡片内容的加载 58 9.3.3 卡片内容的安装 59 9.3.4 卡片内容的加载、安装和可选择化联合操作 59 9.3.5 卡片内容加载过程 59 9.3.6 卡片内容的安装过程 61 9.3.7 卡片内容的可选择化过程 62 9.3.8 卡片内容的加载、安装和可选择化联合操作过程 63 9.3.9 加载和安装流程的示例 65 9.4 内容的让渡和注册表的更新 68 9.4.1 内容的让渡 68 9.4.2 注册表的更新 70 9.4.2.1 普通的注册表更新 70 9.4.2.2 注册表更新中的让渡操作 71 9.5 内容的删除 71 9.5.1 应用删除 72 9.5.2 可执行加载文件的删除 73 9.5.3 可执行加载文件和相关应用的删除 74 9.6 安全管理 75 9.6.1 生命周期管理 76 9.6.2 应用的锁定和解锁 76 9.6.3 卡片的锁定和解锁 77 9.6.4 卡片终结 77 9.6.5 应用状况的查询 78 9.6.6 卡片状况的查询 78 9.6.7 操作的频度检测 79 9.6.7.1 内容加载和安装 79 9.6.7.2 异常 79 9.6.8 跟踪和事件日志 79 9.7 内存资源管理 79 10 安全通信 81 10.1 安全通信 81 10.2 显式和隐式安全通道 81 10.2.1 显式安全通道的开启 81 10.2.2 隐式安全通道的开启 81 10.2.3 安全通道的终止 81 10.3 安全通道协议的直接处理和间接处理 82 10.4 实体认证 82 10.4.1 对称加密算法下的认证 82 10.4.2 非对称加密下的认证 82 10.5 安全的消息传送 83 10.6 安全级别 83 10.7 安全通道协议标识符 83

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值