练习9.31:
第316也中删除偶数值的元素并复制技术值元素的程序不能用于list或forward_list。为什么?修改程序,使之也能用于这些类型。
解答:
首先,316页中的程序主要做的是插入和删除操作,这个操作对于链表容器来说不影响其迭代器和指针。
不过,插入和删除操作会让其他容器的迭代器指针失效。
所以,这里对迭代器所做的处理,就不适合于链表容器了。
这里对forward_list的处理稍稍需要些耐心。
#include <iostream>
#include <vector>
#include <list>
#include <forward_list>
using namespace std;
void vector_func(vector<int>& iv){
auto iter = iv.begin();
while (iter != iv.end()){
if (*iter % 2){
iter = iv.insert(iter, *iter);
iter += 2;
}
else{
iter = iv.erase(iter);
}
}
}
void list_func(list<int>& il){
auto iter = il.begin();
while (iter != il.end()){
if (*iter % 2){
iter = il.insert(iter, *iter);
++iter;
++iter;
}
else {
iter = il.erase(iter);
}
}
}
void forward_list_func(forward_list<int>& ifl){
auto prev = ifl.before_begin();
auto curr = ifl.begin();
while (curr != ifl.end()){
if (*curr % 2){
curr = ifl.insert_after(prev, *prev);
prev = curr;
++curr;
}
else{
curr = ifl.erase_after(prev);
prev = curr;
}
}
}
int main(){
vector<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list<int> ilist(vi.begin(), vi.end());
forward_list<int> forward_ilist(vi.begin(), vi.end());
vector_func(vi);
for (auto i : vi){
cout << i << " ";
}
cout << endl;
list_func(ilist);
for (auto i : ilist){
cout << i << " ";
}
cout << endl;
forward_list_func(forward_ilist);
for (auto i : forward_ilist){
cout << i << " ";
}
cout << endl;
}
在第316页的程序中,想下面语句这样调用insert是否合法?如果不合法,为什么?
iter = vi.insert(iter, *iter++)
解答:
在这个程序中,这样做不合法。会产生迭代器访问越界。
如果要这样改,下面一句
iter += 2; --> ++iter;
这样做才合法,不会出现越界的情况。
练习9.33:
在本节最后一个例子中,如果不讲insert的结果赋予begin,将会发生什么?编写程序,去掉此赋值语句,验证你的答案。
解答:
程序会出错。在容器使用insert以后,迭代器会失效。第二个begin的自加会出错。
练习9.34:
假定vi是一个保存int的容器,其中有偶数值也有奇数值,分析下面循环的行为,然后编写程序验证你的分析是否正确。
iter = vi.begin();
while(iter != vi.end())
if (*iter % 2)
iter = vi.insert(iter, *iter);
++iter;
解答:
不断往第一个奇数后面添加相同的奇数,直到内存耗尽。
所以,这个程序会产生死循环。