描述
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;
}