很经典的"转圈数数踢人"问题,老早以前做的东西
这里是我的解法,利用STL里的List构建Ring List
头文件:
//:This part is partly from Bruce Eckel's source code .
// thought he don't hear of me at all ^_^
// Making a "ring" data structure from the STL
#ifndef RING_H
#define RING_H
#include
#include
using namespace std;
template class Ring{
list lst;
public:
class iterator;
friend class iterator;
class iterator :public std::iterator<:bidirectional_iterator_tag>{
typename list::iterator it;
list* r;
public:
iterator(list&lst,const typename list::iterator& i):it(i),r(&lst){}
bool operator==(const iterator& x)const{
return it==x.it;
}
bool operator!=(const iterator& x)const{
return!(*this==x);
}
typename list::reference operator*()const{
return *it;
}
iterator& operator++(){
++it;
if(it==r->end())
it=r->begin();
return *this;
}
iterator operator++(int){
iterator tmp=*this;
++*this;
return tmp;
}
iterator &operator--(){
if(it==r->begin())
it=r->end();
--it;
return *this;
}
iterator operator--(int){
iterator tmp=*this;
--*this;
return tmp;
}
iterator insert(const Type& x){
return iterator(*r,r->insert(it,x));
}
//I have to recognize that the iterator is not so smart as
//we expected .If the element in the list is erased ,the
//iterator will be lost and point to a null.The shortage of
//the stupid iterator will been seen the the Josephus.cpp
//we have to use a template variable to storage the next iterator
//of the deleting iterator.If not ,the programe will be nightmare
iterator erase(){
return iterator(*r,r->erase(it));
}
};
void push_back(const Type& x){lst.push_back(x);}
iterator begin(){return iterator(lst,lst.begin());}
int size(){return lst.size();}
};
#endif
实现文件:
//:Using circle list to solve Josephus problem
//:version 1.01
//:author Murainwood 12/3/2006
#include
#include"Ring.h"
void main(){
//enter the number of people and the index
int n,m;
cout<
cin>>n>>m;
Ring ring;
for(int i=1;i<=n;i++) ring.push_back(i);
//determine the iterator
//it is reasonable to declare two iterator
Ring::iterator tmp=ring.begin();
Ring::iterator it=tmp;
//without the iterator tmp ,if we erase the it
//the it will lost ,so the loop can not work
for(int index=0;index
it=tmp;
for(int j=0;j
tmp++;
cout<
it.erase();
}
it=ring.begin();
cout<
}
//:finished
这个Ring List有很高的效率和安全性,并且通用性也比较好
这里也发现个问题,就是STL里的Iterator 还不够"聪明",这也是为什么我会在程序里多加个迭代器:tmp,
因为如果我调用了it.erase();那么这个迭代器就丢失了,程序也就无非运行下去.
这样我们很容易地想,如果调用了it.erase()后,指针不是丢失,而是指向下一个元素该多好啊!
很遗憾,现阶段标准STL库里的List没有这个功能.猜想是因为List的物理存储结构的缘故,如果让他的迭代器变得如我们想像得那么"聪明",那么花费可能会有些大.
还没有验证过boost库,不知道那里的迭代器是否会更人性化些
有时间研究一下相关的STL源码,写一个"聪明些"的迭代器.
posted on 2006-04-18 00:10 murainwood 阅读(534) 评论(0) 编辑 收藏 所属分类: C++&C