【c++】8.map和vector容器查找、删除指定元素、emplace、insert
1.查找与删除 vector 和 map 容器中指定元素
vector
查找或删除vector的指定元素"123"
方法1:使用迭代器
不同于map(map有find方法),vector本身没有find这一方法.
std::vector<std::string> vct_name_;
auto iter = vct_name_.begin();
while(iter != vct_name_.end()) {if(*iter=="123"){ // 这命令可以作为查找vetor元素的方法vct_name_.erase(iter); // 删除//iter=vct_name_.erase(iter); //也可以这么写}
}
方法2:使用 std::remove_if
std::vector<std::string> vct_name_;
vct_name_.erase(std::remove_if(vct_name_.begin(),vct_name_.end(),[](std::string str) { return str == "123"; }),vct_name_.end());
map
(1) 查找map的关键字:
std::map<std::string,int> map_name_;
auto iter = map_name_.find("key_name");
if (iter != map_name_.end()) {//找到了该关键字,进行的操作
}
(2) 删除map的指定key值
有多种方法:
正确用法1: 直接删除key
map_name_.erase("key_name");
正确用法2: 使用find()时,可以直接删除迭代器
auto iter = map_name_.find("key_name");
if (iter != map_name_.end()) {map_name_.erase(iter); //删除
}
- 正确用法3:
iter = name_age_map.erase(iter);
- 正确用法4:
map_name_.erase(iter++);
- 错误用法:
map_name_.erase(iter); iter++;
上面 正确用法4
和 错误用法
两种情况执行序列是不相同的:
前者
map_name_.erase(iter++);
在erase执行前进行了加操作,在it被删除(失效)前进行了加操作,是安全的;后者
map_name_.erase(iter); iter++;
是在erase执行后才进行加操作,而此时iter已经被删除(当前的迭代器已经失效了),对一个已经失效的迭代器进行加操作,行为是不可预期的,这种写法势必会导致 map操作的失败并引起进程的异常。
原文链接:https://blog.csdn.net/weixin_43778179/article/details/105157228
以下原文链接:https://blog.csdn.net/nisxiya/article/details/47070827
C++ STL中的map是非常常见的。通常我们用如下方式来遍历,并且删除map中的一些entry:
不安全的删除方法:
map<int, int> mp;
mp.insert(make_pair(1,1));
mp.insert(make_pair(2,3)); // insert some elements
for (map<int, int>::iterator iter = mp.begin(); iter != mp.end(); iter++) {if (iter->first == 1) mp.erase(iter); // Unsafe!else iter->second++;
}
上面的删除并不安全
,因为mp.erase(iter)
之后,iter
的结构已经改变了,此时 for
循环张的iter++
可能会出现问题。因此推荐下面的改法:
安全的删除方法:
for (map<int, int>::iterator iter = mp.begin(); iter != mp.end(); ) {if (iter->first == 1) mp.erase(iter++); // SAFE!else iter->second++;
}
这里的删除是安全
的,因为iter
在删除前已经会先进行缓存一下,再传给erase
去删除。因此iter++
是在原先的iter
基础上进行的。这种方式也是C++
文档中推荐的方式。
2.源码示例
map的erase(iter)需注意,和vector不一样
https://blog.csdn.net/zhangyueweia/article/details/50293965
#include <iostream>
#include <map>
#include <string>
#include <vector>// g++ -std=c++11 main.cpp -o mainint main() {// std::vector可以直接删除iter后不影响遍历std::vector<std::string> name_vct = {"Alibaba", "Baidu", "CMD", "DDS","Ella"};std::vector<std::string>::iterator it = name_vct.begin();while (it != name_vct.end()) {std::cout << "*it= " << *it << std::endl;if (*it == "CMD") {name_vct.erase(it);std::cout << "erase后 *it= " << *it << std::endl;} else {++it;}}std::cout << std::endl;std::map<std::string, int> name_age_map = {{"AAA", 21}, {"Bob", 22}, {"Cool", 23}, {"Daisy", 24}};/** 下面这种方式会出错。 std::map 删除iter后继续遍历会造成double free **//*auto it0 = name_age_map.begin();while (it0 != name_age_map.end()) {std::cout << "key= " << it0->first << std::endl;if (it0->first == "Bob") {name_age_map.erase(it0); //当这条语句执行完后,it0就是一个非法指针,如果再执行++就会出错. std::cout << "erase后 it0->first << std::endl; } else {++it0;}}*//** --方法1* std::map删除iter需要这么使用,使用一个临时变量保存迭代器后,将迭代器自增1**//*while (it1 != name_age_map.end()) {std::cout << "key= " << it1->first << std::endl;if (it1->first == "Bob") {auto iter_tmp = it1;++it1;name_age_map.erase(iter_tmp);std::cout << "erase后 iter_tmp->first= " << iter_tmp->first << std::endl; std::cout << "erase后 it1->first= " << it1->first << std::endl;} else {++it1;}}*//** --方法2* std::map删除iter需要这么使用,it2 = name_age_map.erase(it2);**//*auto it2 = name_age_map.begin();while (it2 != name_age_map.end()) {std::cout << "key= " << it2->first << std::endl;if (it2->first == "Bob") {it2 = name_age_map.erase(it2);std::cout << "erase后 it2->first= " << it2->first << std::endl;} else {++it;}}
*//** --方法3* std::map删除iter需要这么使用,name_age_map.erase(it3++);**/auto it3 = name_age_map.begin();while (it3 != name_age_map.end()) {std::cout << "key= " << it3->first << std::endl;if (it3->first == "Bob") {name_age_map.erase(it3++);std::cout << "erase后 it->first= " << it3->first << std::endl;} else {++it3;}}
}
3. map 的insert和emplace方法
参考地址: https://www.cnblogs.com/khacker/p/10479801.html
对于两种map
容器 std::map
、std::unordered_map
:
insert(std::make_pair(key, value))
和 emplace(std::make_pair(key, value))
重复插入同一个key的操作,二者都不会
替换原先的key对应的value值,只有索引[]
操作会改变value。
以下是验证代码示例:
std::unordered_map<int, int > map;map.insert(std::make_pair(1, 1));map.insert(std::make_pair(2, 2));map.insert(std::make_pair(3, 3));map.insert(std::make_pair(1, 4)); //这一步并不会改变key为1的value值,仍旧是1,不会变为4
std::unordered_map<int, int > map;map.emplace(1, 1);map.emplace(2, 2);map.emplace(3, 3);map.emplace(1, 4); //这一步并不会改变key为1的value值,仍旧是1,不会变为4
map[1] = 1;map[2] = 2;map[3] = 3;map[1] = 4; //这句话会改变key为1的value值,变为4
可以使用以下方式插入key-value
键值对 和 更新键值value
:
- 如果不存在
key
,则使用insert()
和emplace()
进行插入键值对;通过前面的知识,我们知道,也可以直接使用[]
的当时直接插入键,并进行赋值。 - 如果存在
key
,则使用[]
进行赋值;
if(map.count(key)){map.insert(std::make_pair(key, value));map.emplace(std::make_pair(key, value));//map[key]=value; //这种方式也可以
}else{map[key]=value;
}
【c++】8.map和vector容器查找、删除指定元素、emplace、insert相关推荐
- C++ vector容器 find erase的使用:查找并删除指定元素
概念:容器.迭代器.算法 STL包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的优缺点,不同的容器反映出程序设计的不同需求.容器自身可能由数组或链表实现,或者容器中的每个元 ...
- vector删除指定元素
C++ vector中实际删除元素使用的是容器vecrot中std::vector::erase()方法. C++ 中std::remove()并不删除元素,因为容器的size()没有变化,只是元素的 ...
- C/C++ vector 删除指定元素
C++ vector 删除符合条件的元素 C++ vector中实际删除元素使用的是容器vecrot中std::vector::erase()方法. C++ 中std::remove()并不删除元素, ...
- Java 集合List、Set、HashMap操作二(Map遍历、List反向、Set删除指定元素,集合只读、TreeMap操作、List转Array、List移动元素)
Map遍历 import java.util.Map; import java.util.HashMap; import java.util.HashSet; import java.util.Ite ...
- 编写程序获取 vector 容器的第一个元素。分别使用下标 操作符、front 函数以及 begin 函数实现该功能,并提 供空的 vector 容器测试你的程序
/*********************** 编写程序获取 vector 容器的第一个元素.分别使用下标 操作符.front 函数以及 begin 函数实现该功能,并提 供空的 vector 容器 ...
- C# List集合查找删除指定数据
C# List集合查找删除指定数据 文章目录 1.实体类 2.操作第一个负荷条件数据 3.操作所有符合条件数据 4.优质源码 文章目录 1.实体类 public class FaultLevelMod ...
- jq删除数组查找指定值_jquery数组删除指定元素的方法:grep()
jquery数组删除指定元素的方法:grep() 金刚 数组 jquery javascript 元素 遇到的问题 今天遇到一个问题,删除数组中的一个指定元素,并返回新的数组. 我定义的js数组是这样 ...
- js list删除指定元素_删除js数组中的指定元素,有这两步就够了
js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单. 1.JS的数组对 ...
- js数组怎么删除指定元素?
js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单. 1.JS的数组对 ...
最新文章
- 11g RMAN Restore archivelog用法
- HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)
- 2018蓝桥杯省赛---java---A---7(三体攻击)
- 设为首页、加入收藏 兼容代码
- SpringBoot入门一
- Qt工作笔记-主界面传输数据到附属界面(通过信号与槽非构造函数)
- 入秋的第一篇数据结构算法:看看归并与快排的风采,三面蚂蚁金服成功拿到offer
- 终极方案 | 梯子(V*n)导致的远程计算机或设备将不接受连接
- java那块最难_Java哪块最难学?
- POJ 2125 Destroying The Graph Acwing 2325. 有向图破坏(拆点+最小权点覆盖集)
- Cadence元器件封装库
- 银联进件渠道教程-云闪付收银台最新方法(可对接易支付)
- 关于Keil编译程序出现“File has been changed outside the editor,reload?”的解决方法
- 什么是运营商大数据精准获客?
- Android - 获取移动端设备ID标识,分情况
- 100个名著浓缩一句话
- 得年轻人者得天下,新闻客户端如何抓住不看报纸的90后?
- JuiceFS:写流程源码解析+刷盘+数据一致性分析
- Zookeeper节点个数设置
- 手机玩刺激战场显示服务器连接异常,绝地求生刺激战场网络异常怎么办 波动异常解决...