关于约瑟夫环用list实现遇到的奇怪问题
2012-11-30 15:34
519 查看
该问题是在Weiss著的《数据结构与算法分析(C++描述+第三版)习题中的3.6题遇到的
先把自己遇到问题的代码粘出来,本人的编译环境是windows7下的g++ (GCC) 4.6.1#include<iostream> #include<list> using namespace std; int main() { int n=0,m=0,i=0; cout<<"please input the number of player : "<<endl; cin>>n; cout<<"please input the times of transfer"<<endl; cin>>m; list<int> aa; for(i=0;i<n;i++) aa.push_back(i+1); list<int>::iterator itr=aa.begin(); while(aa.size()>1) { for(i=0;i<m;i++) { if(itr==aa.end()) itr=aa.begin(); cout<<*itr++<<endl; cout<<*itr<<endl; } cout<<*itr<<" player game over!"<<endl; itr=aa.erase(itr); } return 0; }先试一种简单的情况,输入n=5,m=1
please input the number of player :
5
please input the times of transfer
1
1
2
2 player game over!
3
4
4 player game over!
5
1
1 player game over!
到此处程序就挂掉了,根据上面的输出,刚开始分析以为第三次进入while后
itr已经指向的值是5,进入for语句cout<<*itr++<<endl;输出itr指向5后自加一次,
然后cout<<*itr<<endl;输入itr指向1,认为itr在最后一个元素做自加运算会自动指向list的第一个位置,按此思路,程序继续往下走把cout<<*itr<<" player game over!"<<endl;打出来,接下来调用erase方法删除第一个元素,把返回值即下一个元素的迭代器给itr,看似没有问题但程序却挂那儿不走了
下面给出找出问题后正确的代码
#include<iostream> #include<list> using namespace std; int main() { int n=0,m=0,i=0; cout<<"please input the number of player : "<<endl; cin>>n; cout<<"please input the times of transfer"<<endl; cin>>m; list<int> aa; for(i=0;i<n;i++) aa.push_back(i+1); list<int>::iterator itr=aa.begin(); // cout<<*aa.begin()<<" "<<*aa.end()<<endl; while(aa.size()>1) { for(i=0;i<m%n;i++) { if(itr==aa.end()) itr=aa.begin(); // cout<<*itr<<endl; itr++; // cout<<*itr<<endl; if(itr==aa.end()) itr=aa.begin(); } cout<<*itr<<" player game over!"<<endl; itr=aa.erase(itr); n--; if(itr==aa.end()) itr=aa.begin(); } cout<<*aa.begin()<<" player win the game!"<<endl; return 0; }
输入同上,输出的结果如下
please input the number of player :
5
please input the times of transfer
1
1 1
1
2
2 player game over!
3
4
4 player game over!
5
1
1 player game over!
3
5
5 player game over!
3 player win the game!
问题其实出在迭代器指向最后一个元素时,做自加运算后itr实际是指向了end标记,
那为什么上面出问题的情形下cout<<*itr<<endl;输出了1呢,难道是巧合吗???
这个我也不知道是不是巧合还是C++标准里有什么特殊的规定,输出的1其实是list中end标记指向的值,
原因可以见cout<<*aa.begin()<<" "<<*aa.end()<<endl;的输出值 1 1
所以当接下来调用erase方法删除end当然就出错了
总结:一些需要做循环操作的程序中,在自加运算前后都要判断迭代器是否指向end,
是的话手动让它指向begin。
本人刚学数据结构和算法,不知道这问题是不是很二,大牛轻拍哈
有兴趣的童鞋可以研究一下迭代器end指向的值是不是都是1或者end指向的值是怎么规定的
相关文章推荐
- 关于jquery解析json数据时动态追加tr 指定条数换行问题 实现list的 并列显示效果
- 安装Piwik时遇到的一个奇怪的关于PHP参数问题的解决办法
- 最近遇到个关于接口的奇怪的问题
- 关于List.addAll(Collection<E>)方法遇到的问题
- 关于使用spring框架来实现email发送其中遇到的问题已解决
- java用list实现约瑟夫环问题
- 关于用bootstrap实现页面中遇到的问题
- 使用 comment-net-ftp-3.5.jar 实现FTPClient时遇到的listFiles()返回空的问题小结
- 遇到一个关于ObjectDataSource的奇怪问题
- Android学习记录(三十)-- Android 关于手势Gesture的简单实现和实践中遇到的问题。
- 关于java synchronized修饰方法时实现线程互斥遇到的问题
- 关于用两块arm实现双视频通信项目所遇到的问题和解决方法
- 关于checkbox全选与全不选的实现与遇到的问题
- 关于android微信QQ等平台分享功能实现中遇到的问题处理
- 关于BadgeView遇到的一个奇怪的问题和解决办法
- 遍历List/Map的时候删除成员遇到的奇怪问题
- gdb时候遇到的奇怪问题(关于返回值)
- 学习Java中所遇到问题,关于为什么List为什么会设置成接口
- 关于在windows2003下面实现mrtg监控所遇到的问题
- 关于vhd做为第二系统在迁移中遇到的奇怪问题