版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://jeick.blog.51cto.com/713059/144272
|
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 { 8 long multiValue = 0; 9 bitCount += log10((long double)index); 10 if(arrValue[begin] == 0) 11 begin++; 12 13 for(int j=begin; j<int(bitCount); ++j) 14 { 15 multiValue += (index*arrValue[j]); 16 arrValue[j] = char(multiValue % 10); 17 multiValue /= 10; 18 } 19 } 这里就是计算的关键了.注意一下进位问题即可.所有代码如下:
1
2/**/// 3// Date created: 2005/07/12 4// Author: Confach Zhang 5// Purpose: 计算n!的值 6/**/// 7 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{ 29 int value=GetNumber(); 30 char fileName[16]; 31 int size=GetBitLength(value); 32 char *pa = Initialize(size); 33 34 //pa=GetValue(); 35 pa=GetValue(value); 36 37 PrintValue(pa,size); 38 39 //sprintf(fileName,"%s","10000!.txt"); 40 sprintf(fileName,"%d!.txt",value); 41 42 PrintValue(pa,size,fileName); 43 delete []pa; //note: 44 return 1; 45} 46//函数GetValue 47// 求得计算结果 48//返回结果 49//History: 50//1)char* GetValue() 51//2)GetValue(int val) 52// 参数:val 计算阶乘的值 53char* GetValue(int val) 54{ 55 //定义一个数组存储阶乘的值 56 //首先得到10000!阶乘的位数 57 int VALUE=val; 58 int length=GetBitLength(VALUE); 59 char *arrValue = new char[length]; 60 if(!arrValue) { 61 cout <<"申请内存失败!" << endl; 62 exit(1); 63 } 64 arrValue[0] = 1; 65 for(int i=1; i<length; i++) 66 arrValue[i] = 0; 67 arrValue=SubGetValue(arrValue,VALUE); 68 return arrValue; 69} 70 71char* SubGetValue(char* arrValue,int n) 72{ 73 int index=0; 74 long carrier=0; 75 double bitCount = 1; 76 int begin = 0; 77 78 for(index=2; index<=n; ++index) 79 { 80 long multiValue = 0; 81 bitCount += log10((long double)index); 82 if(arrValue[begin] == 0) 83 begin++; 84 85 for(int j=begin; j<int(bitCount); ++j) 86 { 87 multiValue += (index*arrValue[j]); 88 arrValue[j] = char(multiValue % 10); 89 multiValue /= 10; 90 } 91 } 92 return arrValue; 93} 94 95//得到计算阶乘的值,此函数为新增 96int GetNumber() 97{ 98 int n; 99 cout << "请输入要计算阶乘的n值: "; 100 cin >> n; 101 while(n < 0) { 102 cout << "输入错误,请重新输入: "; 103 cin >> n; 104 } 105 if(n == 0) 106 exit(1); 107 return n; 108} 109 110//函数GetBitLength 111// 求得计算结果的位数,本函数为新增加 112//参数 113// n 需要计算的阶乘的数 114//返回结果的位数 115int GetBitLength(int n) 116{ 117 double sum = 1.0; 118 for(int i=1; i<=n; i++) 119 sum += log10((long double)i); 120 return int(sum); 121} 122//----------- 123//函数:Initialize 124// 初始化存储结果的数组 125//参数: 126// size 数组的长度 127//返回值 128// 初始化后的数组 129//------------- 130char * Initialize(int size) 131{ 132 char *arrValue = new char[size]; 133 if(!arrValue) { 134 cout << size<<"太大,申请内存失败!" << endl; 135 exit(1); 136 } 137 arrValue[0] = 1; 138 for(int i=1; i<size; i++) 139 arrValue[i] = 0; 140 return arrValue; 141} 142 143//----------- 144//函数:PrintValue 145// 将结果输入到屏幕上 146//参数: 147// buff 存储结果的数组 148// buffLen 数组的长度 149// fileName 文件名 150//------------- 151void PrintValue(char *buff, int buffLen) 152{ 153 int bit = 0; 154 int nCol=0; 155 for(int i=buffLen-1; i>=0; i--) { 156 if(bit % 10 == 0) 157 { 158 cout << " " ; 159 nCol++; 160 if(nCol==10)cout<<endl; 161 } 162 cout << int (buff[i]); 163 bit++; 164 } 165 cout << endl; 166 167} 168//----------- 169//函数:PrintValue 170// 将结果输入到一个文件中 171//参数: 172// buff 存储结果的数组 173// buffLen 数组的长度 174// fileName 文件名 175//------------- 176 177void PrintValue(char *buff,int buffLen,char *fileName) 178{ 179 int bit = 0; 180 int nCol=0; 181 182 FILE *fp=NULL; 183 //----------------------------- 184 185 if (fileName==NULL) return ; 186 fp=fopen(fileName,"wt"); 187 if (fp==NULL) 188 { 189 printf("不能创建文件%s",fileName); 190 return ; 191 } 192 193 for(int i=buffLen-1; i>=0; i--) 194 { 195 fprintf(fp,"%d",int(buff[i])); 196 197 if(bit % 9 == 0) 198 { 199 fprintf(fp,"%s"," "); 200 nCol++; 201 if(nCol==8) 202 { 203 fprintf(fp,"%s","/n"); 204 nCol=0; 205 } 206 } 207 bit++; 208 209 } 210 fprintf(fp,"/n"); 211 fclose(fp); 212} 213 本文出自 “Jeick(编程菜鸟)” 博客,请务必保留此出处http://jeick.blog.51cto.com/713059/144272 |