以前很少做删除操作,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