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::mapstd::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相关推荐

  1. C++ vector容器 find erase的使用:查找并删除指定元素

    概念:容器.迭代器.算法 STL包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的优缺点,不同的容器反映出程序设计的不同需求.容器自身可能由数组或链表实现,或者容器中的每个元 ...

  2. vector删除指定元素

    C++ vector中实际删除元素使用的是容器vecrot中std::vector::erase()方法. C++ 中std::remove()并不删除元素,因为容器的size()没有变化,只是元素的 ...

  3. C/C++ vector 删除指定元素

    C++ vector 删除符合条件的元素 C++ vector中实际删除元素使用的是容器vecrot中std::vector::erase()方法. C++ 中std::remove()并不删除元素, ...

  4. 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 ...

  5. 编写程序获取 vector 容器的第一个元素。分别使用下标 操作符、front 函数以及 begin 函数实现该功能,并提 供空的 vector 容器测试你的程序

    /*********************** 编写程序获取 vector 容器的第一个元素.分别使用下标 操作符.front 函数以及 begin 函数实现该功能,并提 供空的 vector 容器 ...

  6. C# List集合查找删除指定数据

    C# List集合查找删除指定数据 文章目录 1.实体类 2.操作第一个负荷条件数据 3.操作所有符合条件数据 4.优质源码 文章目录 1.实体类 public class FaultLevelMod ...

  7. jq删除数组查找指定值_jquery数组删除指定元素的方法:grep()

    jquery数组删除指定元素的方法:grep() 金刚 数组 jquery javascript 元素 遇到的问题 今天遇到一个问题,删除数组中的一个指定元素,并返回新的数组. 我定义的js数组是这样 ...

  8. js list删除指定元素_删除js数组中的指定元素,有这两步就够了

    js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单. 1.JS的数组对 ...

  9. js数组怎么删除指定元素?

    js数组是js部分非常重要的知识,有时我们有这么个需求js数组删除指定元素,先定义一个函数来获取删除指定元素索引值,然后用js数组删除的方法,来删除指定元素即可,就两步不难,很简单. 1.JS的数组对 ...

最新文章

  1. 11g RMAN Restore archivelog用法
  2. HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)
  3. 2018蓝桥杯省赛---java---A---7(三体攻击)
  4. 设为首页、加入收藏 兼容代码
  5. SpringBoot入门一
  6. Qt工作笔记-主界面传输数据到附属界面(通过信号与槽非构造函数)
  7. 入秋的第一篇数据结构算法:看看归并与快排的风采,三面蚂蚁金服成功拿到offer
  8. 终极方案 | 梯子(V*n)导致的远程计算机或设备将不接受连接
  9. java那块最难_Java哪块最难学?
  10. POJ 2125 Destroying The Graph Acwing 2325. 有向图破坏(拆点+最小权点覆盖集)
  11. Cadence元器件封装库
  12. 银联进件渠道教程-云闪付收银台最新方法(可对接易支付)
  13. 关于Keil编译程序出现“File has been changed outside the editor,reload?”的解决方法
  14. 什么是运营商大数据精准获客?
  15. Android - 获取移动端设备ID标识,分情况
  16. 100个名著浓缩一句话
  17. 得年轻人者得天下,新闻客户端如何抓住不看报纸的90后?
  18. JuiceFS:写流程源码解析+刷盘+数据一致性分析
  19. Zookeeper节点个数设置
  20. 手机玩刺激战场显示服务器连接异常,绝地求生刺激战场网络异常怎么办 波动异常解决...

热门文章

  1. lucene源码分析(1)基本要素
  2. 数据库更新记录,但程序查不到新记录问题
  3. Tomcat7启动报Error listenerStart错误--转载
  4. oracle pde文件导入
  5. nginx多进程模型之配置热加载---转
  6. 【Python】进制转换
  7. 宏定义define的使用
  8. docker tensorflow-jupyter简单使用
  9. 谷歌新 AI 实验室主管 Hugo 深度学习教程:神经网络、CV、NLP 难点解析
  10. 2015年240个数据库引擎排名参考