加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

一个简单的大数实现方案,计算斐波纳契数列

发布时间:2020-12-14 02:57:39 所属栏目:大数据 来源:网络整理
导读:计算斐波那契数列Fn=Fn_1+Fn_2,(PS:千万不要递归)!!!! 《编程之美》2.9计算Fn,提出了三种方案计算Fn,方案一,有线性时空复杂度;方案二,求通项公式,但是好像对于一些编程语言来说没有什么实用性;方案三,引入了矩阵计算有最优的时间复杂度!!

计算斐波那契数列Fn=Fn_1+Fn_2,(PS:千万不要递归)!!!!

《编程之美》2.9计算Fn,提出了三种方案计算Fn,方案一,有线性时空复杂度;方案二,求通项公式,但是好像对于一些编程语言来说没有什么实用性;方案三,引入了矩阵计算有最优的时间复杂度!!!

当然,这里我关心的不是时间复杂度,而是一般计算机能算到斐波那契数列的第几位?

众所周知,long long类型的变量能表示20位无符号整形,利用常规的循环计算,大概能完整的计算出F93



上网百度一个大数解决方案(参考自:http://www.voidcn.com/article/p-mdoamqoa-nv.html?),好好学习了大数的四则运算,大概能算很多位了~~~!

#include<iostream>
#include<cstring>
#include<cassert>
using namespace std;
#define  MAXLENGTH 1000
struct BigInt
{
	//bool isPositive;//表示该数的符号
	int length;
	int s[MAXLENGTH];
};
void Str2BigInt(const char * str,BigInt & x)
{
	x.length=strlen(str);
	for(int i=0;i<x.length;i++)
	{
		assert(str[i]>='0'&& str[i]<='9');//断言
		x.s[x.length-1-i]=str[i]-'0';
	}
	if(x.length==0)
	{
		x.length=1;
		x.s[0]=0;
	}
}
void PrintBigInt(const BigInt& x)
{
	for(int i=x.length-1;i>=0;i--)
		cout<<x.s[i];
}
//大数加法(两个正数的相加)
void PlusBigInt(const BigInt& A,const BigInt& B,BigInt & C)
{
	int i;
	C.s[0]=0;
	for(i=0;i<A.length || i<B.length;i++)//此处用||比用&&程序简洁很多
	{
		if(i<A.length)C.s[i]+=A.s[i];
		if(i<B.length)C.s[i]+=B.s[i];
		C.s[i+1]=C.s[i]/10;//注意里,既计算了该位的值也为下一步的的计算进行了初始化,初始化为零或以1;
		C.s[i]=C.s[i]%10;
	}
	C.length=C.s[i]>0?i+1:i;
}
//大数减法(大数减小数)
void SubBigInt(const BigInt& A,BigInt & C)
{
	//对应为相减A[i]-B[i]-borrow;第i+1位的借位通过上一位的结果判断
	int i=0,borrow=0;
	while(i<A.length)//B是小数
	{
		if(i<B.length)
		    C.s[i]=A.s[i]-B.s[i]-borrow;//正里假象A,B位数相同,(B前面不足的认为是零) 
		else
			C.s[i]=A.s[i]-borrow;
		if(C.s[i]<0)
		{
			borrow=1;
			C.s[i]+=10;
		}
		else
			borrow=0;
		i++;
	}
	while(i>0&&C.s[i]<=0) i--;
	C.length=i+1;
}
//大数乘法
void MultiBigInt(const BigInt& A,BigInt & C)
{
	C.length=A.length+B.length;
	for(int i=0;i<C.length;i++)
		C.s[i]=0;
	int i,j;
	for(i=0;i<B.length;i++)
		for(j=0;j<A.length;j++)
			C.s[i+j]+=A.s[j]*B.s[i];//注意这里是累加
	i=0;
	while(C.s[i]>0)
	{
		C.s[i+1]+=C.s[i]/10;
		C.s[i]=C.s[i]%10;
		i++;
	}
	C.length=i;
}
//大数比较
int CMPBigInt(const BigInt& A,const BigInt& B)
{
	if(A.length>B.length)
		return 1;
	if(A.length<B.length)
		return -1;
	int i=A.length-1;
	while(i>0&&A.s[i]==B.s[i]) i--;
	return A.s[i]-B.s[i];

}

//大数除法
void DivideBigInt(const BigInt& A,BigInt & C,BigInt &D)
{
	//C是商,D是余数
	//类比除法计算
	D.length=1;D.s[0]=0;
	int i,j;
	for(i=A.length-1;i>=0;i--)
	{
		//不断增大D直到大于B
		if(!(D.length==1&&D.s[0]==0))//刚开始时不需要左移
		{
			//需要左移D
			for(j=D.length-1;j>=0;j--)
				D.s[j+1]=D.s[j];
			D.length++;
		}
		//扩充一位
		D.s[0]=A.s[i];
		C.s[i]=0;
		while((j=CMPBigInt(D,B))>=0)
		{
			SubBigInt(D,B,D);
			C.s[i]++;
			if(j==0)
				break;//注意:这里十分巧妙;
		}
	}
	i = A.length - 1;  
    while (i>0 && !C.s[i]>=0) --i;  
    C.length = i+1;  
}
// 大整数置0  
inline void ZeroBigInt(BigInt& x)  
{  
	x.length = 1; x.s[0] = 0;  
}  
// 大整数置1  
inline void OneBigInt(BigInt& x)  
{  
	x.length = 1; x.s[0] = 1;  
}

int main(int argc,char *argv[])
{
	//求科波菲尔第4000项;
	BigInt Fn_1,Fn_2,Fn,zero;
	ZeroBigInt(zero);
	ZeroBigInt(Fn_2);
	OneBigInt(Fn_1);
	int N=2;
	while(N<=93)
	{
		PlusBigInt(Fn_1,Fn);
		PlusBigInt(zero,Fn_1,Fn_2);
		PlusBigInt(zero,Fn_1);
		N++;
	}
	PrintBigInt(Fn);
	cout<<endl;
	N=2;
	unsigned long long fn_1=1,fn_2=0;
	unsigned long long fn;
	while(N<=93)
	{
		fn=fn_1+fn_2;
		fn_2=fn_1;
		fn_1=fn;
		N++;
	}
	cout<<fn;
	system("pause");
	return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读