Прежде всего, вы можете использовать std::advance(*this,l);
вместо этого цикла while
в вашем конструкторе.Но!Ваш подход крайне неэффективен , потому что он должен вычислять последовательность Фибоначчи дважды : один, чтобы знать, что является последним числом Фибоначчи, и второй, чтобы фактически получить его, когда используется ++
по клиентскому коду.
Я думаю, что лучшим подходом было бы сохранить индекс числа Фибоначчи last
из конструктора в закрытом элементе и сравнивать счетчик с ним после каждого ++
.Его можно повторно использовать из уже существующего поля index
, сделав его следующим образом:
Пусть конструктор по умолчанию инициализирует итератор Фибоначчи fib0 = 0
, fib1 = 1
и index = 0
.Другой конструктор (параметрический) будет создавать фиктивный итератор, который содержит только последний индекс последовательности, а другие поля недопустимы.Этот один итератор будет итератором «один за другим», только для сравнения индексов, а не для чтения значений.
Итак, вот мое решение:
#include <iterator>
class Fibonacci : public iterator<input_iterator_tag, int>
{
unsigned index;
value_type fib0, fib1;
public:
Fibonacci(): index(0), fib0(0), fib1(1) { }
explicit Fibonacci(unsigned last): index(last), fib0(0), fib1(0) { }
bool operator == (const Fibonacci& other) { return index == other.index; }
bool operator != (const Fibonacci& other) { return !(*this == other); }
value_type operator * () const { return fib0; }
Fibonacci& operator ++ () {
++index;
value_type fnew = fib0 + fib1;
fib0 = fib1; fib1 = fnew;
return *this;
}
Fibonacci operator ++ (int) {
Fibonacci current(*this);
++(*this);
return current;
}
};
#include <iostream>
#include <algorithm>
int main()
{
using namespace std;
ostream_iterator<int> out(cout, "; ");
cout << "Fibonacci numbers from 0th to 19th:\n";
copy(Fibonacci(), Fibonacci(20), out);
cout << endl;
}
Вывод:
Fibonacci numbers from 0th to 19th:
0; 1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89; 144; 233; 377; 610; 987; 1597; 2584; 4181;
Как вы можете видеть, в моем примере также есть многократное повторное использование кода: я повторно использую операторы внутри других операторов, вызывая их.
Конечно, это работает только для чисел, вписывающихся в int
,Было бы лучше переписать его, чтобы использовать числа с множественной точностью (например, библиотека GMP).