随手画了一个图小结一下:
下面是根据书中的例子写的一些代码:
#include <iostream>
#include <vector>
#include "Triangulate_iterator.h"
using namespace std;
static int arr[13] = {1,1,2,3,5,8,13,21,34,55,89,144,233};
class Triangulate_iterator;
class Triangulate {
public:
typedef Triangulate_iterator iterator;
/*申明Triangulate_iterator为Triangulate的友元,
Triangulate_iterator里的函数都能对Triangulate的私有成员进行访问了
*/
friend class Triangulate_iterator;
Triangulate();
Triangulate(int length , int beg_pos);
Triangulate(int length);
Triangulate(const Triangulate&);
Triangulate_iterator begin();
Triangulate_iterator end();
friend int operator* (const Triangulate_iterator &rhs);
int length() const { return _length; }
int beg_pos() const { return _beg_pos; }
int length() { return _length; }
int beg_pos() { return _beg_pos; }
bool next(int &x) const;
void next_reset() const;
static bool is_elem( int );
static int get_elem( int pos ) {
return _elem[pos];
}
static void gen_elements( int length );
static void gen_elems_to_value( int value );
static void display( int length, int beg_pos, ostream &os = cout );
static vector<int> _elem;
private:
string _name;
int _length;
int _beg_pos;
mutable int _next;
static const int _max_elems = 1024;
};
class Triangulate_iterator {
public:
friend class Triangulate;
Triangulate_iterator(int index) : _index(index-1) {}
friend int operator* (const Triangulate_iterator &rhs);
bool operator== ( const Triangulate_iterator& ) const;
bool operator!= ( const Triangulate_iterator& ) const;
int Triangulate_iterator::operator* (const Triangulate_iterator &rhs);
Triangulate_iterator& operator++ ();
Triangulate_iterator operator++ ( int );
private:
void check_integrity() const; //检查 _index是否合理
int _index;
};
class iterator_overflow{
};
int operator* (const Triangulate_iterator &rhs) {
rhs.check_integrity();
return Triangulate::_elem[rhs._index];
}
inline bool Triangulate_iterator::operator == ( const Triangulate_iterator& rhs ) const {
return this->_index == rhs._index;
}
inline bool Triangulate_iterator::operator != ( const Triangulate_iterator& rhs ) const {
return (! (*this == rhs ));
}
inline
int Triangulate_iterator::operator* (const Triangulate_iterator &rhs) {
rhs.check_integrity();
return Triangulate::_elem[_index];
}
Triangulate_iterator& Triangulate_iterator::operator++ () {
_index++;
check_integrity();
return *this;
}
Triangulate_iterator Triangulate_iterator::operator++ ( int ) {
Triangulate_iterator tem = *this;
_index++;
check_integrity();
return tem;
}
inline
void Triangulate_iterator::check_integrity() const {
if ( _index >= Triangulate::_max_elems)
throw iterator_overflow();
if(_index >= Triangulate::_elem.size())
Triangulate::gen_elements( _index + 1);
}
Triangulate_iterator Triangulate::begin() {
return Triangulate_iterator(_beg_pos);
}
Triangulate_iterator Triangulate::end() {
return Triangulate_iterator(_beg_pos + _length);
}
Triangulate::Triangulate()
: _name("Triangulate"),_length(1),_beg_pos(1),_next(0) {}
Triangulate::Triangulate(int l, int b) : _name("Triangulate") {
_length = l > 0 ? l : 1;
_beg_pos = b > 0 ? b : 1;
_next = _beg_pos-1;
}
Triangulate::Triangulate(int l) : _name("Triangulate") {
_length = l > 0 ? l : 1;
_beg_pos = 1;
_next = _beg_pos - 1;
}
Triangulate::Triangulate(const Triangulate &rhs) {
_length = rhs._length;
_beg_pos = rhs._beg_pos;
_next = rhs._next;
_name = rhs._name;
}
bool Triangulate::next(int &elem) const {
if(_next >= _length)
return false;
elem = _elem[_next];
_next++;
return true;
}
void Triangulate::next_reset() const {
_next = _beg_pos - 1;
}
vector<int> Triangulate::_elem;
int sum( const Triangulate &trian ) {
if ( !trian.length())
return 0;
int sum = 0;
int val = 0;
trian.next_reset();
while ( trian.next( val ))
sum += val;
return sum;
}
bool Triangulate::is_elem( int value ) {
if ( !_elem.size() || _elem[_elem.size()-1] < value)
gen_elems_to_value(value);
vector<int>::iterator found;
vector<int>::iterator last = _elem.end();
found = find(_elem.begin(), last, value);
return found != last;
}
void Triangulate::gen_elems_to_value( int value ) {
int ix = _elem.size();
if ( !ix ) {
_elem.push_back(1);
ix = 1;
}
if ( ix == 1) {
_elem.push_back(1);
ix = 2;
}
while ( _elem[ix-1] < value && ix < _max_elems) {
_elem.push_back(_elem[ix-2] + _elem[ix-1]);
ix++;
}
if( ix == _max_elems )
cerr << " value too large " << value << " -- exceeds max size of "
<< _max_elems << endl;
}
void Triangulate::gen_elements( int length ) {
if ( length <= 0 || length > _max_elems )
return;
int ix = _elem.size();
if ( length == 1 && ix < length ) {
_elem.push_back(1);
ix++;
}
if ( length == 2 && ix < length ) {
if( ix == 0) {
_elem.push_back(1);
++ix;
}
_elem.push_back(1);
++ix;
}
for (; ix < length; ix++ ) {
_elem.push_back(_elem[ix-2] + _elem[ix-1]);
}
}
int main() {
char ch;
bool more = true;
int i = Triangulate::_elem[0];
while( more ) {
cout << "Enter your value ";
int value;
cin >> value;
cout << "the value " << (Triangulate::is_elem(value) ? "is " : "is not ")
<< "the element of the Triangulate "
<< " try more (y/n) " << endl;
cin >> ch;
if ( ch=='y' || ch=='Y' ) {
more = true;
} else
more = false;
}
return 0;
}