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;

posted @ 2016-04-18 00:44  Harley_Quinn  阅读(1987)  评论(0编辑  收藏  举报