10000的阶乘的算法(大数的阶乘) [转]
2006-05-23 21:06
375 查看
很多天没有更新自己的Blog了,前几天拿到一个题目.就是写一段程序计算10000的阶乘.当时我还以为这题目非常简单,没想到还是需要动点大脑的.花了将近半个小时才搞定,拿出来分享一下.
为什么不能用普通的方法来写呢,比如说递归?在我的教科书上可是用的是递归呀?不知道你注意没有,如果是100的阶乘的话,其结果肯定是非常大的,以我们现有语言的数据类型肯定是没法使用的,就拿C来说,long型能存的下10000的阶乘吗?未必.所以我就使用数组来存储结果的每一位,然后输出每一位不就是结果吗.
那么具体怎样去做?
首先确定结果的位数?如何确定呢?请看下面.
2!=1*2<=10*10
3!=1*2*3<=10*10*10
.......
所以我们可以得出一个结论
n!<=10n
所以n!的位数可以这样计算:
两边取对数,即log10n!<=log1010n
两边n>=Log101+Log102+Log10 3+....Log10 n
这样n!的位数肯定等于小于Log101+Log102+Log10 3+....Log10 n.
以上是错误的
正确的推断如下:
可以将n!表示成10的次幂,即n!=10^M(10的M次方)则不小于M的最小整数就是 n!的位数,
对该式两边取对数,有=log10^n!即:
M = log10^1+log10^2+log10^3...+log10^n
循环求和,就能算得M值,该M是n!的精确位数。
位数的确定解决之后,就看看如何计算了.
看看如下代码:
1int index=0;
2 long carrier=0;
3 double bitCount = 1;
4 int begin = 0;
5
6 for(index=2; index<=n; ++index)
7
2// Date created: 2005/07/12
4// Author: Confach Zhang
5// Purpose: 计算n!的值
6
8
9using namespace std;
10#include "StdAfx.h"
11#include <iostream.h>
12#include <conio.h>
13#include <stdlib.h>
14#include <math.h>
15#include <stdio.h>
16#include <iomanip.h>
17
18int GetNumber(); //输入 n
19int GetBitLength(int n); //求n!的位数
20char* Initialize(int); //初始化存储结果的值
21void PrintValue(char *a,int size); //打印值到屏幕
22void PrintValue(char *a,int size,char* fileName); //打印值到文件
23char* GetValue(int val); //计算
24char* SubGetValue(char* ,int);
25
26
27int main()
28//函数GetValue
47// 求得计算结果
48//返回结果
49//History:
50//1)char* GetValue()
51//2)GetValue(int val)
52// 参数:val 计算阶乘的值
53char* GetValue(int val)
54
71char* SubGetValue(char* arrValue,int n)
72
95//得到计算阶乘的值,此函数为新增
96int GetNumber()
97
//函数GetBitLength
// 求得计算结果的位数,本函数为新增加
//参数
// n 需要计算的阶乘的数
//返回结果的位数
int GetBitLength(int n)
//-----------
//函数:Initialize
// 初始化存储结果的数组
//参数:
// size 数组的长度
//返回值
// 初始化后的数组
//-------------
char * Initialize(int size)
//-----------
//函数:PrintValue
// 将结果输入到屏幕上
//参数:
// buff 存储结果的数组
// buffLen 数组的长度
// fileName 文件名
//-------------
void PrintValue(char *buff, int buffLen)
//-----------
//函数:PrintValue
// 将结果输入到一个文件中
//参数:
// buff 存储结果的数组
// buffLen 数组的长度
// fileName 文件名
//-------------
void PrintValue(char *buff,int buffLen,char *fileName)
好了,不说了.
下载代码
本贴转自:http://confach.cnblogs.com/archive/2005/07/14/192703.html
为什么不能用普通的方法来写呢,比如说递归?在我的教科书上可是用的是递归呀?不知道你注意没有,如果是100的阶乘的话,其结果肯定是非常大的,以我们现有语言的数据类型肯定是没法使用的,就拿C来说,long型能存的下10000的阶乘吗?未必.所以我就使用数组来存储结果的每一位,然后输出每一位不就是结果吗.
那么具体怎样去做?
首先确定结果的位数?如何确定呢?请看下面.
2!=1*2<=10*10
3!=1*2*3<=10*10*10
.......
所以我们可以得出一个结论
n!<=10n
所以n!的位数可以这样计算:
两边取对数,即log10n!<=log1010n
两边n>=Log101+Log102+Log10 3+....Log10 n
这样n!的位数肯定等于小于Log101+Log102+Log10 3+....Log10 n.
以上是错误的
正确的推断如下:
可以将n!表示成10的次幂,即n!=10^M(10的M次方)则不小于M的最小整数就是 n!的位数,
对该式两边取对数,有=log10^n!即:
M = log10^1+log10^2+log10^3...+log10^n
循环求和,就能算得M值,该M是n!的精确位数。
位数的确定解决之后,就看看如何计算了.
看看如下代码:
1int index=0;
2 long carrier=0;
3 double bitCount = 1;
4 int begin = 0;
5
6 for(index=2; index<=n; ++index)
7
2// Date created: 2005/07/12
4// Author: Confach Zhang
5// Purpose: 计算n!的值
6
8
9using namespace std;
10#include "StdAfx.h"
11#include <iostream.h>
12#include <conio.h>
13#include <stdlib.h>
14#include <math.h>
15#include <stdio.h>
16#include <iomanip.h>
17
18int GetNumber(); //输入 n
19int GetBitLength(int n); //求n!的位数
20char* Initialize(int); //初始化存储结果的值
21void PrintValue(char *a,int size); //打印值到屏幕
22void PrintValue(char *a,int size,char* fileName); //打印值到文件
23char* GetValue(int val); //计算
24char* SubGetValue(char* ,int);
25
26
27int main()
28//函数GetValue
47// 求得计算结果
48//返回结果
49//History:
50//1)char* GetValue()
51//2)GetValue(int val)
52// 参数:val 计算阶乘的值
53char* GetValue(int val)
54
71char* SubGetValue(char* arrValue,int n)
72
95//得到计算阶乘的值,此函数为新增
96int GetNumber()
97
//函数GetBitLength
// 求得计算结果的位数,本函数为新增加
//参数
// n 需要计算的阶乘的数
//返回结果的位数
int GetBitLength(int n)
//-----------
//函数:Initialize
// 初始化存储结果的数组
//参数:
// size 数组的长度
//返回值
// 初始化后的数组
//-------------
char * Initialize(int size)
//-----------
//函数:PrintValue
// 将结果输入到屏幕上
//参数:
// buff 存储结果的数组
// buffLen 数组的长度
// fileName 文件名
//-------------
void PrintValue(char *buff, int buffLen)
//-----------
//函数:PrintValue
// 将结果输入到一个文件中
//参数:
// buff 存储结果的数组
// buffLen 数组的长度
// fileName 文件名
//-------------
void PrintValue(char *buff,int buffLen,char *fileName)
好了,不说了.
下载代码
本贴转自:http://confach.cnblogs.com/archive/2005/07/14/192703.html
相关文章推荐
- 10000的阶乘的算法(大数的阶乘)
- 10000的阶乘的算法(大数的阶乘)
- 10000的阶乘的算法(大数的阶乘)
- 求大数阶乘算法(华为2015面试题)
- 另一种求大数阶乘的算法
- WV.27-大数阶乘算法7-入门篇之二
- 另一种求大数阶乘的算法
- 大数——10000以内的阶乘
- N的阶乘(大数阶乘算法)
- 算法 大数计算:加减乘除,模,阶乘,进制转换(大数除法取余)
- 2018年全国多校算法寒假训练营练习比赛(第三场)E---进击吧!阶乘(Java代码,另附Java解决大数问题的模板)
- WV.21-大数阶乘算法1-序
- WV.28-大数阶乘算法8-入门篇之三汇编的威力
- 求大数阶乘的算法
- 大数阶乘算法
- 2018年全国多校算法寒假训练营练习比赛(第三场)---E---题(大数阶乘(模板题)c++/java/py)
- 2018年全国多校算法寒假训练营练习比赛题解(第三场)E进击吧!阶乘(大数运算)
- 另一种求大数阶乘的算法
- [原创]阶乘(1000的阶乘,10000的阶乘...)以及大数相乘(几十万位乘几十万位)
- VBS函数应用--求大数的阶乘的算法