9.3.6节练习

练习9.31:第316页中删除偶值元素并复制奇值元素的程序不能用于list或者forward_list。为什么?修改程序,使之也能用于这些类型。

316页代码:

//傻瓜循环,删除偶数元素,复制奇数元素
vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin(); //调用begin而不是cbegin,因为我们要改变vi
while(iter != vi.end()){
    if(*iter % 2){
        iter = vi.insert(iter, *iter);//复制当前元素
        iter += 2; //向前移动迭代器,跳过当前元素以及插入到它之前的元素
    } else
        iter = vi.erase(iter);   //删除偶数元素
        // 不应向前移动迭代器,iter指向我们删除的元素之后的元素
}

insert 在指定位置之前插入一个元素

insert_after 在指定位置之后插入  

二者都是返回 最后插入的那个元素的迭代器。

答:不能用于list是因为  list的迭代器不支持 算数加的操作  只能每次加一个 

不能用于forward_list 除了上述原因  还因为它要使用自己特定版本的insert_after和erase_after

修改  适合list:

//傻瓜循环,删除偶数元素,复制奇数元素
list<int> vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin(); //调用begin而不是cbegin,因为我们要改变vi
while(iter != vi.end()){
    if(*iter % 2){
        iter = vi.insert(iter, *iter);//复制当前元素
        iter ++; //向前移动迭代器,跳过当前元素以及插入到它之前的元素
        iter ++; 
    } else
        iter = vi.erase(iter);   //删除偶数元素
        // 不应向前移动迭代器,iter指向我们删除的元素之后的元素
}

修改  适合forward_list:

//傻瓜循环,删除偶数元素,复制奇数元素
forward_list<int> vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin(); //调用begin而不是cbegin,因为我们要改变vi
auto prev = vi.before_begin();
while(iter != vi.end()){
    if(*iter % 2){
        iter = vi.insert_after(iter, *iter);//复制当前元素
        iter ++; //向前移动迭代器,跳过当前元素以及插入到它之前的元素
        prev++;
        prev++;
    } else
        iter = vi.erase_after(prev);   //删除偶数元素
        // 不应向前移动迭代器,iter指向我们删除的元素之后的元素
}

练习9.32:在第316页的程序中,向下面语句这样调用insert是否合法?如果不合法,为什么?

iter = vi.insert(iter, *iter++);

答:不合法  因为 insert操作改变了容器的大小   迭代器将失效   再进行自加操作将会报错。 

练习9.33:在本节最后一例中,如果不将insert的结果赋予begin,将会发生什么?编写程序,去掉此赋值语句,验证你的答案。

答:没有必要验证   删除之后肯定迭代器失效   然后运行中断

练习9.34: 假定vi是一个保存int的容器,其中有偶数值也有奇数值,分析下面循环的行为,然后编写程序验证你的分析是否正确。

iter = vi.begin();
while(iter != vi.end()){
    if(*iter % 2)
        iter = vi.insert(iter, *iter);
        ++iter;
}

答:原书代码里面自加没有进循环  所以是死循环

进循环后  由于只加了一次 所以 如果有一个奇数 那依然每次都是死循环。

猜你喜欢

转载自blog.csdn.net/xnnswmzdszyd/article/details/89677962
今日推荐