首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用库调用在C#中计算阶乘?

如何使用库调用在C#中计算阶乘?
EN

Stack Overflow用户
提问于 2009-09-30 02:34:30
回答 6查看 44.1K关注 0票数 8

我需要计算数字的阶乘,直到100左右!为了确定一系列抛硬币样式的数据是否是随机的,正如您在那里看到的那样,根据this Wikipedia entry on Bayesian probability.,必要的公式涉及3个阶乘计算(但有趣的是,其中两个阶乘计算是在计算第三个阶乘计算的过程中进行的)。

我看到了this question here,但我认为整数很快就会被放大。我也可以做一个关于阶乘计算的更智能的函数(例如,如果我有11!/(7.3!),根据维基的例子,我可以去(11*10*9*8)/3!),但这对我来说有点过早优化的味道,在某种意义上我希望它能工作,但我不关心速度(目前)。

那么,为了获得这种概率,我可以调用什么好的C#库来计算阶乘呢?我对阶乘计算中的所有惊人之处都不感兴趣,我只想要一种我可以操纵它的结果。在Math命名空间中似乎没有阶乘函数,因此出现了问题。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-09-30 02:38:36

你可以试试Math.NET --我还没有用过那个库,但是他们确实列出了阶乘和对数阶乘。

票数 8
EN

Stack Overflow用户

发布于 2009-09-30 02:37:20

已经有一个类似主题的previous question。有人在那里链接了Fast Factorial Functions网站,其中包括一些对有效算法的解释,甚至还有C#源代码。

票数 4
EN

Stack Overflow用户

发布于 2009-09-30 02:50:54

你想计算阶乘,还是二项式系数?

听起来你想要计算二项系数--特别是你提到11!/(7.3!)。

也许有一个库可以帮你做到这一点,但作为访问堆栈溢出的(可能)程序员,没有理由不自己编写一个。这并不是很复杂。

为了避免内存溢出,在删除所有公共因素之前,不要评估结果。

这个算法仍然需要改进,但是你已经有了一个好的算法的基础。为了获得最佳结果,需要将分母值拆分为它们的质因数。按照目前的情况,这将非常快地运行到n= 50。

代码语言:javascript
复制
float CalculateBinomial(int n, int k)
{
    var numerator = new List<int>();
    var denominator = new List<int>();
    var denominatorOld = new List<int>();

    // again ignore the k! common terms
    for (int i = k + 1; i <= n; i++)
        numerator.Add(i);

    for (int i = 1; i <= (n - k); i++)
    {
        denominator.AddRange(SplitIntoPrimeFactors(i));
    }

    // remove all common factors
    int remainder;                
    for (int i = 0; i < numerator.Count(); i++)
    {
        for (int j = 0; j < denominator.Count() 
            && numerator[i] >= denominator[j]; j++)
        {
            if (denominator[j] > 1)
            {
                int result = Math.DivRem(numerator[i], denominator[j], out remainder);
                if (remainder == 0)
                {
                    numerator[i] = result;
                    denominator[j] = 1;
                }
            }
        }
    }

    float denominatorResult = 1;
    float numeratorResult = 1;

    denominator.RemoveAll(x => x == 1);
    numerator.RemoveAll(x => x == 1);

    denominator.ForEach(d => denominatorResult = denominatorResult * d);
    numerator.ForEach(num => numeratorResult = numeratorResult * num);

    return numeratorResult / denominatorResult;
}

static List<int> Primes = new List<int>() { 2, 3, 5, 7, 11, 13, 17, 19, 
    23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

List<int> SplitIntoPrimeFactors(int x)
{
    var results = new List<int>();
    int remainder = 0;

    int i = 0;
    while (!Primes.Contains(x) && x != 1)
    {
        int result = Math.DivRem(x, Primes[i], out remainder);
        if (remainder == 0)
        {
            results.Add(Primes[i]);
            x = result;
            i = 0;
        }
        else
        {
            i++;
        }
    }
    results.Add(x);
    return results;
}

我可以估计n= 110,k= 50 (返回6x10^31),但不能运行n= 120,k= 50。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1495856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档