一个简单的大数实现方案,计算斐波纳契数列
2014-11-02 14:38
399 查看
计算斐波那契数列Fn=Fn_1+Fn_2,(PS:千万不要递归)!!!!
《编程之美》2.9计算Fn,提出了三种方案计算Fn,方案一,有线性时空复杂度;方案二,求通项公式,但是好像对于一些编程语言来说没有什么实用性;方案三,引入了矩阵计算有最优的时间复杂度!!!
当然,这里我关心的不是时间复杂度,而是一般计算机能算到斐波那契数列的第几位?
众所周知,long long类型的变量能表示20位无符号整形,利用常规的循环计算,大概能完整的计算出F93
上网百度一个大数解决方案(参考自:/article/8867684.html ),好好学习了大数的四则运算,大概能算很多位了~~~!
《编程之美》2.9计算Fn,提出了三种方案计算Fn,方案一,有线性时空复杂度;方案二,求通项公式,但是好像对于一些编程语言来说没有什么实用性;方案三,引入了矩阵计算有最优的时间复杂度!!!
当然,这里我关心的不是时间复杂度,而是一般计算机能算到斐波那契数列的第几位?
众所周知,long long类型的变量能表示20位无符号整形,利用常规的循环计算,大概能完整的计算出F93
上网百度一个大数解决方案(参考自:/article/8867684.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,const BigInt& B,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,const BigInt& B,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,const BigInt& B,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_2,Fn); PlusBigInt(zero,Fn_1,Fn_2); PlusBigInt(zero,Fn,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; }
相关文章推荐
- C++实现的一个简单两个大数相加程序!
- 实现一个简单的服务端推送方案-实例篇Polling(服务端阻塞读)
- 实现一个简单的服务端推送方案-实例篇Push
- 6-8 简单阶乘计算(10 分) 本题要求实现一个计算非负整数阶乘的简单函数。
- 一个简单的分布式锁实现方案
- 一个mfc实现的简单计算功能
- 一个简单的jQuery计算器实现了连续计算功能
- 用原生JS实现一个简单计算的功能实例
- 转:实现一个简单的服务端推送方案
- python实现一个简单泰勒的计算
- 实现一个简单的服务端推送方案-实例篇Polling
- 实现一个简单的服务端推方案
- 一个简单的文件服务器实现方案
- 实现一个简单的数学计算题
- 实现一个简单的服务端推方案
- 实现一个简单的服务端推送方案-实例篇Push
- java实现一个简单的HTTP服务器,带打开网页和计算功能
- 一个简单的Java计算器实现
- 自行控制loadrunner的socket协议性能测试 (转) 一前言 二任务的提出 三实现方案讨论 四技术要点讲解 如何开始录制一个最简单的收发数据包脚本 写日志文件 一行一行读数据包文件 字
- JAVA实现一个简单的代数运算语言编译器(四)-- 表达式计算