大数 斐波那契 与阶乘
来源:互联网 发布:安知玉如意百度云 编辑:程序博客网 时间:2024/05/18 02:36
此代码 之所以能得到1--40000的斐波那契数 主要是内存用得少 循环加法 当然 如果要得到 100万 要改改size 另外求解的时间也要增加我试了试 用这个 得到 第40万个数 需要 大约1分钟 只要是 前 10万都很快 # include <stdlib.h># include <stdio.h># define M 1000000000/*每一个int存9位*/# define size 9290/*第40万个斐波那契需要9290个int的存储空间*/# define MAX 400000int add(int a[][size],int d);void main(){int shu[3][size]={0,0,0},num,wei=0,k;/*初始化shu[][];*/while(wei<1||wei>MAX){printf("显示第几个斐波纳挈数?(1--%d):\n",MAX);scanf("%d",&wei);while(getchar()!='\n');}k=num=add(shu,wei);wei=(wei-1)%3; printf("%d",shu[wei][num--]);while(num>0)printf("%09d",shu[wei][num--]); printf("\n比%d多(0--9)位%d",(k-1)*9,shu[wei][1]%10007); getchar();}int add(int a[][size],int b){int i,j,m,k,c[]={0,1,2},index=1;a[0][1]=a[1][1]=1;/*初值为1 1*/for (i=1;i<=b;i++){for (j=1;j<=index; j++)a[c[2]][j]=a[c[0]][j]+a[c[1]][j];for (k=1;k<index; k++)if (a[c[2]][k]>=M) {a[c[2]][k+1]+=a[c[2]][k]/M; /* 当前位向前进位 */a[c[2]][k]%=M; /*当前位进位之后的值 */} while (a[c[2]][index] >= M&& index <= size-1){a[c[2]][index+1] = a[c[2]][index]/M; /* 向最高位进位 */a[c[2]][index++]%=M; /* 进位之后的值,位数+1*/}for(m=0;m<3;m++)c[m]=(c[m]+1)%3;//对c[0--2]循环做加法} return index;}
阶乘:
大数字阶乘 int 与unsigned __int64类型存储方式与计算速度的比较大数字阶乘已经是老掉牙的东西了,有 斯特林快速求解阶乘的近似公式 还有利用double求精准位数的高手……,不过今天要说的是求精确值的算法,在开始学阶乘的运算时大概都是递归开始 递归慢不如迭代法 之后又用char存储,每个存一位。但是当数字达到20000时发现慢的要死;之后又改为int 存储,一个int存一位,速度快了一点,但是内存浪费严重 如果求30000的阶乘要开辟121288个int的空间相当于 121288*4个字节 如果再高点 如果40000 那么 内存太大 虽然编译没问题 但是程序一运行就挂了 之后又改为一个int存4位 速度更快了 内存也降下来了 求30000的阶乘需要30322个int空间 ,但是我还想更快 更节省内存 不由的想到了把 int改为 __int64 或者unsigned __int64 在测试中我放弃了__int64因为它虽然比int快但不如unsigned __int64快。之后测试 确定了 一个 unsigned __int64 存14位那么 结果如何呢?速度更快了。这个快不仅体现在运算上,还体现在输出时间上。下面是int和unsigned __int64的代码://int 一个int存4位#include <stdio.h>#define SIZE 77200 //30000!有121288位,但是每四位进一位,所以即使是40000!也只用到41279位,50000! 53310*4位左右# define N 10000 /*10000不要改效率更快*/ //60000! 65195*4位左右 7000! 77920左右int BigFact(int m, int data[]);//计算m的阶乘void main(){int data[SIZE] = {0}; /*存储SIZE位数,元素全部初始化为0,data[0]空着 */int index,j,n=0; /* 数组元素个数,表示阶乘值的位数 */ while(n<1||n>70000) {printf("输入n int 求n!4 (1-70000)注:\n10000!用时约2秒\n20000!用时约5秒\n30000!用时约11秒\n40000!用时约21秒\n50000!用时约37秒\n60000!用时约52秒\n70000!用时约73秒\n");scanf("%d", &n);while(getchar()!='\n');}printf("%d!=\n", n);n=index = BigFact(n,data);/* 计算阶乘n!,返回阶乘值的位数 */if (index) /* 检验数组是否溢出,若未溢出,则打印阶乘值 */printf("%d",data[index--]);while(index>0)printf("%04d",data[index--]);printf("\n位数大约为%d±4位\n ",n*4);getchar();}/*函数功能:计算m!,存于数组data中,若数组未溢出,则返回阶乘值的位数,否则返回0*/int BigFact(int m, int data[]){ int i, j, k;int index = 1; /* 数组元素个数,表示阶乘值的位数 */data[1] = 1; /* 初始化,令1!=1 */for (i=1; i<=m; i++) /* 计算阶乘m!*/{for (j=1; j<=index; j++)data[j]=data[j] * i;/*每一位数字都乘以i,模仿乘法计算*/for (k=1;k<index; k++)if (data[k]>=N) /*阶乘值的每位数字应在0~9之内若>=10,则进位*/{data[k+1]+=data[k]/N; /* 当前位向前进位 */data[k]%=N;/*当前位进位之后的值 */}/* 单独处理最高位,若计算之后的最高位>=10,则位数index加1 */while (data[index] >=N && index <= SIZE-1){data[index+1] = data[index]/N; /* 向最高位进位 */data[index]%=N; /* 进位之后的值 */index++; /* 位数index加1 */}}return index <= SIZE-1?index:0;/* 检验数组是否溢出,若未溢出,则返回阶乘值的位数 */}接下来为unsigned __int64 #include <stdio.h>#define SIZE 22056 typedef unsigned __int64 elem;const unsigned __int64 N=100000000000000;//一个elem存14位int BigFact(elem m,elem data[]);//计算m的阶乘void main(){elem data[SIZE] = {0}; /*存储SIZE位数,元素全部初始化为0,data[0]空着 */int index,n=0; /* 数组元素个数,表示阶乘值的位数 */ while(n<1||n>70000) {printf("输入n求n!14位 unsigned __int64(1-70000)注:\n10000!用时约1秒\n20000!用时约5秒\n30000!用时约11秒\n40000!用时约21秒\n50000!用时约34秒\n60000!用时约50秒\n70000!用时约70秒\n");scanf("%I64u", &n);while(getchar()!='\n');}printf("%I64u!=\n", n);n=index = BigFact(n,data);/* 计算阶乘n!,返回阶乘值的位数 */if (index) /* 检验数组是否溢出,若未溢出,则打印阶乘值 */printf("%I64u",data[index--]);while(index>0)printf("%014I64u",data[index--]);printf("\n位数大约为%d±14位 占用空间%d个unsigned__int64\n ",n*14,n);getchar();}/*函数功能:计算m!,存于数组data中,若数组未溢出,则返回阶乘值的位数,否则返回0*/int BigFact(elem m,elem data[]){ int i, j, k;int index = 1; /* 数组元素个数,表示阶乘值的位数 */data[1] = 1; /* 初始化,令1!=1 */for (i=1; i<=m; i++) /* 计算阶乘m!*/{for (j=1; j<=index; j++)data[j]=data[j] * i;/*每一位数字都乘以i,模仿乘法计算*/for (k=1;k<index; k++)if (data[k]>=N) /*阶乘值的每位数字应在0~9之内若>=10,则进位*/{data[k+1]+=data[k]/N; /* 当前位向前进位 */data[k]%=N;/*当前位进位之后的值 */}/* 单独处理最高位,若计算之后的最高位>=10,则位数index加1 */while (data[index] >=N && index <= SIZE-1){data[index+1] = data[index]/N; /* 向最高位进位 */data[index++]%=N; /* 进位之后的值 位数index加1 */}}return index <= SIZE-1?index:0;/* 检验数组是否溢出,若未溢出,则返回阶乘值的位数 */}比较一下 : 阶乘! 时间(秒): int unsigned __int6410000 2 1 20000 5 4.530000 11 10.540000 21 2050000 37 3460000 52 4970000 73 70输出速度因为unsigned __int64是以%014I64d输出一次14位 而 int 是%04d 输出一次4位 明显int输出慢
3 0
- 大数 斐波那契 与阶乘
- 阶乘与斐波那契数的理解
- 斐波那契数列与阶乘---递归实现
- 递归 阶乘 斐波那契数列
- 大数斐波那契数列
- Hduoj1865 【大数斐波那契】【水题】
- 斐波那契大数问题
- 斐波那契数列{大数问题}
- 大数斐波那契数列
- 斐波那契数列+大数加法
- 斐波那契数列大数加法
- 大数相加+斐波那契数列
- java大数 斐波那契数列
- 大数斐波那契问题
- 大数加法 + 斐波那契数列
- 大数 阶乘1-7万 斐波那契1-40万 n^M次幂 2^2--70000^60000次幂
- 【HD 1865】 1string ( 大数与斐波那契数列 )
- 蓝桥杯第四届 黄金连分数(大数 斐波那契数列与黄金分割)
- MySQL与PostgreSQL:该选择哪个开源数据库?哪一个更好?
- linux 线程控制
- ELK用户管理
- Codeforces 742A Arpa’s hard exam and Mehrdad’s naive cheat 打表+水题
- Redis数据类型-String
- 大数 斐波那契 与阶乘
- tableView内的View悬停在导航栏的效果
- 常见的Python面试题+详细解答
- Python爬虫爬取Html中的Url常用知识
- spring mvc <mvc:annotation-driven/> 和<context:component-scan base-package=""/>解释
- Redis数据类型-List
- 修复miniblink无法显示某个网站的某个图标的bug
- Codeforces 742B B. Arpa’s obvious problem and Mehrdad’s terrible solution
- android入门小知识