对阶乘算法感兴趣的朋友,请看这个帖子:擂台赛:计算n!(阶乘)的精确值,速度最快者2000分送上

liangbch 2003-09-24 09:59:10
http://expert.csdn.net/Expert/TopicView1.asp?id=2267097
...全文
574 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
micheal882 2003-10-30
  • 打赏
  • 举报
回复
看到大家的,感觉自己好渺小啊。
  • 打赏
  • 举报
回复
呵呵,我的程序,保证时间最短;
大家骂吧,不过“分”嘛...

switch(n)
{
case 1:
res=1;
brake;
case 2:
...

}
















/////////////开玩笑的啦,看到大家的,感觉自己好渺小啊。
pkuniba 2003-10-30
  • 打赏
  • 举报
回复
计算阶乘还有这么多道道
,呵呵
,偶真是
井底之蛙



whtech 2003-10-28
  • 打赏
  • 举报
回复
做个记号,下回来看。
wow303 2003-10-18
  • 打赏
  • 举报
回复
MATLAB里面有现成的函数。
ThenLong 2003-10-10
  • 打赏
  • 举报
回复
呵呵,解决大数相乘先。。。
会快速傅立叶变换吗?不会,那就硬着头皮乘吧:(:(
分段乘,效率还可以。。。
lanyahuhu 2003-10-10
  • 打赏
  • 举报
回复
mark
wh_xiexing 2003-09-28
  • 打赏
  • 举报
回复
z_j() 说到的算法最好
pcitman 2003-09-27
  • 打赏
  • 举报
回复
我正考虑以32位为基数快呢,还是以10的N次方为基数快。(总体时间)
Gelim 2003-09-27
  • 打赏
  • 举报
回复
楼主,既然这么大,就存到硬盘好了!
liangbch 2003-09-26
  • 打赏
  • 举报
回复
to wwwllg(wwwllg):
我从2000。10月就注册了csdn论坛账户。
to z_j() :
如果要查找的数十分有限,而且经常需要用到阶乘,这种方法很有效,但是我的问题是计算几千几万的阶乘,而且可以计算出任一个数的阶乘,故这种方法需要存储空间十分巨大,简直不可能使用。
z_j 2003-09-26
  • 打赏
  • 举报
回复
曾经看过一篇文章讲到了算法与实际应用的关系,其中讲到一个应用需要用到阶乘,从应用出发,它直接把需要的阶乘先计算出来(算法效率如何无所谓),然后放到一个码表里,直接查,(就象初中时用到的对数表),要用的时候直接查表,简单又快捷。

愚人之见,欢迎批评
yangwanfu 2003-09-26
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<stdio.h>
#define MAXN 1000
void pnext(int a[],int k)
{
int *b,m=a[0],i,j,r,carry;
b=(int *) malloc(sizeof(int)*(m+1));
for(i=1;i<=m;i++)
b[i]=a[i];
for(j=1;j<k;j++)
{
for(carry=0,i=1;i<=m;i++)
{
r=(i<a[0]?a[i]+b[i]:a[i])+carry;
a[i]=r%10;
carry=r/10;
}
if(carry)
a[++m]=carry;
}

free(b);
a[0]=m;
}

void write(int *b,int k)
{
int i;
printf("%4d!=",k);
for(i=a[0];i>0;i--)
printf("%d",a[i]);
printf("\n\n");
}


void main()
{
int a[MAXN],n,k;
printf("Please enter the number n: ");
scanf("%d",&n);
a[0]=1;a[1]=1;write(a,1);
for(k=2;k<=n;k++)
{
pnext(a,k);
write(a,k);
getchar();
}
}










UDX协议 2003-09-26
  • 打赏
  • 举报
回复
为什么你的可用分是我的一倍,我很少问问题的.
donger2003 2003-09-25
  • 打赏
  • 举报
回复
用c或c++编个程序就可以嘛!
liangbch 2003-09-25
  • 打赏
  • 举报
回复
我是该贴的楼主,我的可用分有12000多分,如果达到我的要求,一定给分,决不食言。
daylight1980 2003-09-25
  • 打赏
  • 举报
回复
看看
LiRiverhappy 2003-09-25
  • 打赏
  • 举报
回复
总体思路:先使用Stirling公式估算出阶乘的结果
有多少位,然后动态的分配一个数组,分段作乘法。

1.Stirling's Formula
____ 1
n! ~ n^n * e^(-n) * √2nπ * ( 1 + ----- )
12n
对等式取对数,忽略最后部分 ( n > 20 )

lg(n!) ~ n*(lg(n)-lg(e)) + 0.5*( lg(2nπ))

因此,n! 的位数应该是
[ n*(lg(n)-lg(e)) + 0.5*( lg(2nπ)) ] + 1

比如1000!用上式计算出有2568位。

如果我们用4字节的unsigned int作为存储单元,则
一个单元最大为 2^32 - 1 = 4294967295。
最简单的做法,可以假设每个单元存储100000,
则可以最大计算42949! ( 保证不溢出,即
42949 * 100000 < 2^32 )
对于1000!则分配 2568/5 = 514, 即unsigned int[514]

每次计算的时候,循环,用i遍乘每个存储单元,
然后每个单元内的值除以100000的商加到下一个单元,
余数保留在本单元内。
输出的时候,除了最高位单元以外,其余的单元按照5位
输出,不足位用"0"占位。

大致的思路就是这样。可以改进的地方很多。
比如:

1.最后的若干位都是0。n越大,0越多。计算的时候,
又占空间,又占时间。可以考虑每凑够5个0就消掉,
最后纪录一下消掉了多少个单元就可以了。

2.用100000这种10的整幂只是为了输出时方便,
也可以用其他的方式,输出的时候调整一下就可
以了。
3.可以将100!,200!,....存放在一个文件里,当计算的
时候,可以load出最接近的一个,比如存放了500!,
则1000! = 500! * 501 * ... * 1000.这样节约了很多
计算。

xxking 2003-09-25
  • 打赏
  • 举报
回复
up
fanfyj 2003-09-24
  • 打赏
  • 举报
回复
up
加载更多回复(14)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧