1. 程式人生 > >Essential C++ 第五章程式碼

Essential C++ 第五章程式碼

版本一(5.1~5.6內容)

#include <iostream>
#include <vector>

using namespace std;

class num_sequence{
public:
    virtual ~num_sequence() {};

    virtual int elem(int pos) const = 0;
    virtual const char* what_am_i() const = 0;
    static int max_elem() { return _max_elems;}
    virtual ostream& print(ostream &os = cout ) const = 0;

protected:
    virtual void gen_elems(int pos) const = 0;
    bool check_integrity(int pos, int size) const;

    const static int _max_elems = 25;

};

bool num_sequence::check_integrity(int pos,int size) const
{
    if (pos <= 0 || pos >= _max_elems)
    {
        cerr << "!! invalid position: " << pos
             << " Cannot honor request.\n";
        return false;
    }

    if (pos > size)
        gen_elems(pos);

    return true;
}

ostream& operator<<( ostream &os, const num_sequence &ns)
{
    return ns.print( os);
}

class Fibonacci:public num_sequence{
public:
    Fibonacci( int len = 1, int beg_pos = 1)
            : _length(len), _beg_pos(beg_pos) {}

    virtual int elem(int pos) const;
    virtual const char* what_am_i() const { return "Fibonacci";}
    virtual ostream& print( ostream &os = cout) const;
    int length() const { return _length;}
    int beg_pos() const { return _beg_pos;}

protected:
    virtual void gen_elems(int pos) const;
    int _length;
    int _beg_pos;
    static vector<int> _elems;
};

vector<int>  Fibonacci::_elems;

int Fibonacci::elem(int pos) const
{
    if (! check_integrity(pos,_elems.size()))
        return 0;

    return _elems[pos-1];
}

void Fibonacci::gen_elems(int pos) const
{
    if (_elems.empty())
    {
        _elems.push_back(1);
        cout << "gen_elems: 1\n";
        _elems.push_back(1);
        cout << "gen_elems: 1\n";
    }

    if (_elems.size() <= (unsigned)pos)
    {
        int ix = _elems.size();
        int n_2 = _elems[ix-2];
        int n_1 = _elems[ix-1];

        for(; ix < pos; ++ix)
        {
            int elem = n_2 + n_1;
            cout << "gen_elems: " <<elem << endl;
            _elems.push_back(elem);
            n_2 = n_1;
            n_1 = elem;

        }
    }
}

ostream& Fibonacci::print(ostream &os) const
{
    int elem_pos = _beg_pos - 1;
    int end_pos = elem_pos + _length;

    if ( (unsigned)end_pos > _elems.size() )
        Fibonacci::gen_elems(end_pos);

    while (elem_pos < end_pos)
        os << _elems[elem_pos++] << ' ';

    return os;
}

class Triangular:public num_sequence{
public:
    Triangular( int len = 1, int beg_pos = 1)
            : _length(len), _beg_pos(beg_pos) {}

    virtual int elem(int pos) const;
    virtual const char* what_am_i() const { return "Triangular";}
    virtual ostream& print( ostream &os = cout) const;
    int length() const { return _length;}
    int beg_pos() const { return _beg_pos;}

protected:
    virtual void gen_elems(int pos) const;
    int _length;
    int _beg_pos;
    static vector<int> _elems;
};

vector<int>  Triangular::_elems;

int Triangular::elem(int pos) const
{
    if (! check_integrity(pos,_elems.size()))
        return 0;

    return _elems[pos-1];
}

void Triangular::gen_elems(int pos) const
{
    if (_elems.size() <= (unsigned)pos)
    {
        int ix = _elems.size() ? _elems.size()+1 : 1;
        for( ; ix <= pos; ++ix)
        {
            _elems.push_back(ix*(ix+1)/2);
            cout << "gen_elems: " << *(--_elems.end()) << endl;
        }

    }

}

ostream& Triangular::print(ostream &os) const
{
    int elem_pos = _beg_pos - 1;
    int end_pos = elem_pos + _length;

    if ( (unsigned)end_pos > _elems.size() )
        Triangular::gen_elems(end_pos);

    while (elem_pos < end_pos)
        os << _elems[elem_pos++] << ' ';

    return os;
}

inline void display(const num_sequence &ns, int pos, ostream &os = cout)
{
    os << "The element at position " << pos
       << " for the " << ns.what_am_i() << " sequence is "
       << ns.elem(pos) << endl;
}


int main()
{
    Fibonacci fib;
    cout << fib << endl << endl;
    Fibonacci fib2(6);
    cout << fib2 << endl << endl;
    Fibonacci fib3(5,8);
    cout << fib3 << endl;
    cout << fib3.elem(20) << endl;
    Triangular tri(2,5);
    cout << tri << endl;

    display(tri,20);

}



版本二(5.7~5.10)

#include <iostream>
#include <vector>
#include <typeinfo>

using namespace std;

class num_sequence{
public:
    virtual ~num_sequence() {};

//    virtual const char* what_am_i() const = 0;

    int elem(int pos) const;
    int length() const { return _length;}
    int beg_pos() const { return _beg_pos;}

    static int max_elem() { return _max_elems;}

    ostream& print(ostream &os = cout ) const;

    inline const char* what_am_i() const { return typeid(*this).name();}



protected:
//    virtual void gen_elems(int pos) const = 0;
    bool check_integrity(int pos, int size) const;

    virtual void gen_elems(int pos) const = 0;

    const static int _max_elems = 25;

    num_sequence(int len, int bp, vector<int> &re )
        : _length(len), _beg_pos(bp), _relems(re) {}


    int _length;
    int _beg_pos;
    vector<int> &_relems;

};

bool num_sequence::check_integrity(int pos,int size) const
{
    if (pos <= 0 || pos >= _max_elems)
    {
        cerr << "!! invalid position: " << pos
             << " Cannot honor request.\n";
        return false;
    }

    if (pos > size)
        gen_elems(pos);

    return true;
}

int num_sequence::elem(int pos) const
{
    if (! check_integrity(pos,_relems.size()))
        return 0;

    return _relems[pos-1];
}

ostream& num_sequence::print(ostream &os) const
{
    int elem_pos = _beg_pos - 1;
    int end_pos = elem_pos + _length;

    if ( (unsigned)end_pos > _relems.size() )
        gen_elems(end_pos);

    os << what_am_i() << " (" << length() << "," << beg_pos() << "): " ;

    while (elem_pos < end_pos)
        os << _relems[elem_pos++] << ' ';

    return os;
}

class Fibonacci:public num_sequence{
public:
    Fibonacci( int len = 1, int beg_pos = 1)
        : num_sequence(len, beg_pos, _elems) {}

//    virtual const char* what_am_i() const { return "Fibonacci";}

protected:
    virtual void gen_elems(int pos) const;
    static vector<int> _elems;
};

vector<int>  Fibonacci::_elems;

void Fibonacci::gen_elems(int pos) const
{
    if (_elems.empty())
    {
        _elems.push_back(1);
//        cout << "gen_elems: 1\n";
        _elems.push_back(1);
//        cout << "gen_elems: 1\n";
    }

    if (_elems.size() <= (unsigned)pos)
    {
        int ix = _elems.size();
        int n_2 = _elems[ix-2];
        int n_1 = _elems[ix-1];

        for(; ix < pos; ++ix)
        {
            int elem = n_2 + n_1;
//            cout << "gen_elems: " <<elem << endl;
            _elems.push_back(elem);
            n_2 = n_1;
            n_1 = elem;

        }
    }
}

class Triangular:public num_sequence{
public:
    Triangular( int len = 1, int beg_pos = 1)
        : num_sequence(len, beg_pos, _elems) {}

//    virtual const char* what_am_i() const { return "Triangular";}

protected:
    virtual void gen_elems(int pos) const;
    static vector<int> _elems;
};

vector<int>  Triangular::_elems;

void Triangular::gen_elems(int pos) const
{
    if (_elems.size() <= (unsigned)pos)
    {
        int ix = _elems.size() ? _elems.size()+1 : 1;
        for( ; ix <= pos; ++ix)
        {
            _elems.push_back(ix*(ix+1)/2);
//            cout << "gen_elems: " << *(--_elems.end()) << endl;
        }

    }
}

ostream& operator<<( ostream &os, const num_sequence &ns)
{
    return ns.print( os);
}

inline void display(const num_sequence &ns, int pos, ostream &os = cout)
{
    os << "The element at position " << pos
       << " for the " << ns.what_am_i() << " sequence is "
       << ns.elem(pos) << endl;
}

int main()
{
    Fibonacci fib;
    cout << fib << endl;
    Fibonacci fib2(6);
    cout << fib2 << endl;
    Fibonacci fib3(5,8);
    cout << fib3 << endl;
    Fibonacci fib4(fib3);
    Fibonacci fib5 = fib4;
    cout << fib5 << endl;


    Triangular tri(2,5);
    cout << tri << endl;
    display(tri,20);
}



版本二中,return typeid(*this).name(),會分別返回"9Fibonacci","10Triangular",前面的數字表示的是後面字串的長度....怎麼去掉..不知.....