描述
Fibonacci数列指的是数列第一项和第二项为1,之后每一项是之前两项的和所构成的数列。 现有多组数据,每组数据给出一个数字n,请你输出Fibonacci数列的前n-1项。
#include <iostream>
#include <iterator>
using namespace std;template<class T1, class T2>
void Copy(T1 s, T1 e, T2 x) {for(; s != e; ++s, ++x)*x = *s;
}
// 在此处补充你的代码
int main() {while(true) {int n;cin >> n;if(n == 0)break;Fib f1(1), f2(n);ostream_iterator<int> it(cout, " ");Copy(f1, f2, it);cout << endl;}return 0;
}
输入
每组数据一行,整数n
输入以0结尾
输出
对每组数据输出前 n-1项
样例输入
3 0
样例输出
1 1
解题分析
先介绍一下<ostream_iterator>类型。
ostream_iterator
是 C++ 标准库中的一个模板类,属于 <iterator>
头文件。它是一种输出迭代器,用来将值写入到输出流中,如标准输出流(std::cout
)、文件流等。ostream_iterator
是处理输出流的一种便捷方式,尤其在与算法库结合使用时。
基本用法
ostream_iterator
的模板声明如下:
template <class T, class charT = char, class traits = std::char_traits<charT>>
class ostream_iterator;
这里:
T
是要输出的数据类型。charT
是字符类型,默认为char
。traits
是字符特征类型,默认为std::char_traits<char>
,它提供字符处理的基本服务。
构造函数
ostream_iterator
主要有两个构造函数:
-
指定输出流和分隔符:
ostream_iterator(ostream_type& s, const charT* delimiter = 0);
其中 s
是输出流的引用,delimiter
是可选的字符串,指定每次输出后插入的分隔符。
2.拷贝构造函数:
ostream_iterator(const ostream_iterator& other);
以下是使用 ostream_iterator
输出一组整数的例子:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>int main() {std::vector<int> nums = {1, 2, 3, 4, 5};// 创建一个 ostream_iterator 对象,关联到 std::cout,元素之间用空格分隔std::ostream_iterator<int> out_it(std::cout, " ");// 使用 copy 算法输出 nums 中的所有元素std::copy(nums.begin(), nums.end(), out_it);return 0;
}
输出结果为:
1 2 3 4 5
ostream_iterator
通常用于:
- 将容器中的内容输出到控制台或文件。
- 在使用标准算法如
std::copy
,std::transform
等时,作为一种方便的输出手段。
总之,ostream_iterator
提供了一种简单的方法来将数据从容器或算法直接输出到各种流中。
代码演示
#include <iostream>
#include <iterator>
using namespace std;template<class T1, class T2>
void Copy(T1 s, T1 e, T2 x) {for(; s != e; ++s, ++x)*x = *s;
}long long fib[500]={0};
struct Fib
{int n;long long int num;Fib(int a) : n(a){if(fib[n]){num=fib[n];}else{fib[1]=fib[2]=1;for(int i=3;i<=n;i++){fib[i]=fib[i-1]+fib[i-2];}num=fib[n];}}long long int operator*(){return num;}bool operator!=(const Fib& b){return n!=b.n;}void operator++(){n++;if(fib[n]){num=fib[n];}else{fib[1]=fib[2]=1;for(int i=3;i<=n;i++){fib[i]=fib[i-1]+fib[i-2];}num=fib[n];}}
};int main() {while(true) {int n;cin >> n;if(n == 0)break;Fib f1(1), f2(n);ostream_iterator<int> it(cout, " ");Copy(f1, f2, it);cout << endl;}return 0;
}
注意重载Fib类中的*运算符和++运算符即可。
下面附上大整数实现版本:
#include <iostream>
#include <iterator>
using namespace std;template<class T1, class T2>
void Copy(T1 s, T1 e, T2 x) {for(; s != e; ++s, ++x){*x = *s;}
}struct Bigint{string num;Bigint():num("0"){}Bigint(const char* s) : num(s) {}Bigint(string s) : num(s) {}Bigint(int n){if(n==0){num="0";}else{while(n){num=char(n%10+'0')+num;n/=10;}}}Bigint operator+(const Bigint& o){int a[1000]={0},b[1000]={0},c[1000]={0};int len1=num.size();int len2=o.num.size();for(int i=0,j=len1-1;j>=0;i++,j--){a[i]=num[j]-'0';}for(int i=0,j=len2-1;j>=0;i++,j--){b[i]=o.num[j]-'0';}int len=max(len1,len2)+3;int tmp=0;for(int i=0;i<len;i++){c[i]=a[i]+b[i]+tmp;tmp=c[i]/10;c[i]%=10;}if(tmp){c[len]=tmp;}int pos=len;while(c[pos]==0){pos--;}string ans;for(int i=pos;i>=0;i--){ans+=char(c[i]+'0');}return Bigint(ans);}operator bool(){return num!="0";}bool operator!=(const Bigint& a){return num!=a.num;}friend ostream& operator<<(ostream& o,const Bigint& a){o<<a.num;return o;}void operator=(const Bigint& o){num=o.num;}operator int(){return stoi(num);}
};Bigint fib[500]={"0","1","1"};
struct Fib
{int n;Bigint num;Fib(int a) : n(a){if(fib[n]){num=fib[n];}else{for(int i=3;i<=n;i++){fib[i]=fib[i-1]+fib[i-2];}num=fib[n];}}Bigint operator*(){return num;}bool operator!=(const Fib& b){return n!=b.n;}void operator++(){n++;if(fib[n]){num=fib[n];}else{for(int i=3;i<=n;i++){fib[i]=fib[i-1]+fib[i-2];}num=fib[n];}}
};int main() {while(true) {int n;cin >> n;if(n == 0)break;Fib f1(1), f2(n);ostream_iterator<string> it(cout, " ");Copy(f1, f2, it);cout << endl;}return 0;
}