C++中如何在顺序容器中删除符合特定条件的元素

以前很少做删除操作,vector一直当成数组用,而实际追求效率时又经常舍弃vector选用C风格数组。看《C++ Primer》到顺序容器删除这节时试着实现课后习题结果一动手我就出错了。

习题是将数组int ia[]拷贝到std::vector<int>中,并删除偶数元素。

先给出我的错误代码

	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	vector<int> v(begin(ia), end(ia));
	for (auto iter = v.begin(); iter != v.end(); ++iter)
	{
		if (!(*iter % 2))
			v.erase(iter);
	}

抛出异常:vector iterator not incrementable,迭代器不可递增。

原因很简单,因为迭代器都被删除了……所以要用到erase函数的返回值来赋给iter,如果删除成功则把那句v.erase(iter);改成iter = v.erase(iter);否则就直接++iter。

于是for循环第三部分没什么用,干脆改成while循环,发现书上都有几乎一模一样的示例(好吧,毕竟书太厚,以为很熟悉的地方就一目十行了=。=)

更改后如下

	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	vector<int> v(begin(ia), end(ia));
	auto iter = v.begin();
	while (iter != v.end())
	{
		if (*iter % 2)
			++iter;
		else
			iter = v.erase(iter);
	}

这也体现了当年上数据结构时做课程作业马虎的错,当时实现基本数据结构时很多函数都没实现完整,其实数据结构学好了容器也会很容易上手,因为了解了大致流程。

不用容器,直接删除数组ia中的偶数,代码如下

	const unsigned cLength = 11;
	unsigned size = cLength;  // 数组新的大小
	int ia[cLength] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	int index = 0;
	for (int n = 0; n < cLength; ++n) // n只代表访问次数
	{
		if (ia[index] % 2)
			index++;
		else // 元素为偶数
		{
			--size; // 数组大小减1
			// 被删除元素后面的元素前移动
			for (unsigned j = index; j < size; j++)
				ia[j] = ia[j + 1];
			// 元素下标不变
		}
	}
	cout << "删除后数组大小: " << size << "\n新的数组元素如下:\n";
	for (int i = 0; i < size; i++)
		cout << ia[i] << " ";
	cout << endl;

时间: 2024-10-28 09:51:22

C++中如何在顺序容器中删除符合特定条件的元素的相关文章

SqlSever基础 delete 删除符合特定条件的元素

y 镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 table code 1 use helloworld 2 select * from Teacher 2 table show 3 key code 1 --我准备删除燃灯古佛,这一项 2 delete from Teacher where Name='燃灯古佛' 4 key code

JSP页面中如何注入Spring容器中的bean

第一步在JSP页面中导入下面的包: <%@page import="org.springframework.web.context.support.WebApplicationContextUtils" %> <%@page import="org.springframework.web.context.WebApplicationContext" %> 第二步:获取实例 WebApplicationContext context=WebAp

查找二叉树中符合特定条件的值

总结了一下基本用到的公式. 下面用数组存了下,循环求解了 /* 满二叉树:一棵深度为h,且有2的(h)次方-1个节点的二叉树 特点:每一层上的结点数都是最大结点数 它的叶子数是: 2^(h-1) 第k层的结点数是: 2^(h-1) 总结点数是: 2^h-1 (2的k次方减一) 总节点数一定是奇数.所以 2^h-1=127,得出h=7.叶子数为:2^(h-1)=2^(7-1)=64 ----------------------------------------------------------

C++ Primer 第四版读书笔记(八)之顺序容器

容器容纳特定类型对象的集合. 标准库vector类型,是一个顺序容器.它将单一类型元素聚集起来称为容器,然后根据位置来存储和访问这些元素,这就是顺序容器.顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定. 标准库定义了三种顺序容器类型:vector.list和deque.它们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价.标准库还提供了三种容器适配器.实际上,适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型. 顺序容器类型 顺

javascript--函数的声明及调用/JS中代码执行顺序

[函数的声明及调用] 1.函数声明格式: function 函数名(参数1,参数2,参数3--){ //函数体 return 结果: } 函数调用的格式: 函数名(参数1的值,参数2的值,--): 事件调用:事件名=函数名(): 2.函数声明的几点强调: ① 函数的声明,必须符合小驼峰法则(首字母小写,之后每个单词首字母大写): ② 参数的列表,可以有参数,可以无参数.分别称为有参函数,无参函数: ③ 声明函数时的参数列表,称为"形参列表"(变量的名): 调用函数时的参数列表,称为&q

隔离 docker 容器中的用户

笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果你已经了解了 Linux 的 user namespace 技术(参考<Linux Namespace : User>),那么自然会问:docker 为什么不利用 Linux user namespace 实现用户的隔离呢?事实上,docker 已经实现了相关的功能,只是默认没有启用而已.笔者将在

k8s 集群容器中集成arthas、netstat即时诊断分析工具

背景:k8s 集群中,java应用容器中添加即时工具分析诊断arthas.netstat 1.预先下载好arthas-packaging-3.1.1-bin.zip文件,在Dockerfile同目录下,并且重命名为arthas.zipwget http://repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/3.1.1/arthas-packaging-3.1.1-bin.zip mv arthas-packaging-3.1.1-

SpringBoot中在普通类里面加载Spring容器中的类

前言 在我们的工作中,经常会遇到需要在普通类中使用放在Spring容器中的类的情况.最常见的情况大概就是有一个类他的属性的是通过spring的配置文件读取的.这样这个类必然要交给Spring容器进行管理.这个时候如果我们在普通类中直接new这个类是不可以拿到的.属性值不会加载成功.下面介绍一个方法. 实现 封装一个beanutil 我们获取spring容器中的类,都从这个工具类里面来获取. import org.springframework.context.ConfigurableApplic

第九章:顺序容器

一.顺序容器概述:一个容器就是一些特定类型对象的集合 1.顺序容器类型:vector.deque.list.forward_list.array.string string和vector将元素保存在连续的内存空间,所以用下标访问很快,但是在中间位置添加或删除元素很耗时 list和forward_list在任何位置添加和删除操作都很快,但是访问一个元素只能遍历它,而且额外的内存开销很大 forward_list设计的目的是与最好的手写的单向链表数据结构相当的性能 deque支持下标访问,且在两端添