C++Primer第四版习题9.26答案调试出错的解决

习题9.26原答案出错的解决

解决代码如下:

#include <iostream>
include <vector>
include <list>
using namespace std;

int main()
{
    int a[]={0,1,1,2,3,5,8,13,21,55,89};
    int cnt=sizeof(a)/sizeof(int);
    vector<int> ivec_a(a,a+cnt);
    list<int> ilist_a(a,a+cnt);

    for(vector<int>::iterator viter=ivec_a.begin();viter!=ivec_a.end();)
    {
    //代码的关键部分是这里,原答案认为删除指定元素后,迭代器指向下一个元素,
    //所以应该减一,以便在原答案的for循环里自动加1,但经过调试发现当删除一个
    //元素后,再次调用begin()函数发现容器的开始处已经由原先的0变成了1;
    //此时若是把返回来的viter减1为0,则出现未定义,所以报错。
        if(0==*viter%2)
            viter=ivec_a.erase(viter);
        else viter++;
    }
    for (list<int>::iterator liter=ilist_a.begin();liter!=ilist_a.end();)
    {
        if (0!=*liter%2)
            liter=ilist_a.erase(liter);
        else liter++;
    }

    cout<<"New vector is:"<<endl;
    for(vector<int>::iterator viter=ivec_a.begin();viter!=ivec_a.end();viter++)
        cout<<*viter<<' ';
    cout<<endl;
    cout<<"New list is:"<<endl;
    for (list<int>::iterator liter=ilist_a.begin();liter!=ilist_a.end();liter++)
        cout<<*liter<<' ';
    cout<<endl;
    return 0;
}

所以现在的解决方法是删除后迭代器是自动指向被删除元素的下一个元素,那么就不必对迭代器进行任何操作,下次循环正好对被删除元素的下一个元素操作,反而在没有删除时,需要手动更新迭代器的指向,指向容器中的下一个元素。
假设我们把头两个数换成8,9,将代码稍作修改,会发现在将第一个8删除之后,再去调用begin函数,那么产生的新迭代器是指向9的,也就是说删除一个元素之后,容器本身就进行了更新,此时删除8之后viter指向了新容器的begin处,所以不能进行减操作。

int a[]={8,9,1,2,3,5,8,13,21,55,89};
int cnt=sizeof(a)/sizeof(int);
vector<int> ivec_a(a,a+cnt);
list<int> ilist_a(a,a+cnt);
for(vector<int>::iterator viter=ivec_a.begin();viter!=ivec_a.end();viter++)
{
    if(0==*viter%2)
        viter=ivec_a.erase(viter);
    viter--;
    vector<int>::iterator newviter=ivec_a.begin();
    //此时newviter指向9
}

这道题正好在容器的开头处,所以出现报错,但是如果在容器中间的话,删除之后也是不能减的,原因大家应该也清楚了,不过应该不会报错,只是逻辑不对,同一个元素处理了两次。

以上代码测试于VS2005,如有错误,望帮忙指正,谢谢!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值