我需要计算数字的阶乘,直到100左右!为了确定一系列抛硬币样式的数据是否是随机的,正如您在那里看到的那样,根据this Wikipedia entry on Bayesian probability.,必要的公式涉及3个阶乘计算(但有趣的是,其中两个阶乘计算是在计算第三个阶乘计算的过程中进行的)。
我看到了this question here,但我认为整数很快就会被放大。我也可以做一个关于阶乘计算的更智能的函数(例如,如果我有11!/(7.3!),根据维基的例子,我可以去(11*10*9*8)/3!),但这对我来说有点过早优化的味道,在某种意义上我希望它能工作,但我不关心速度(目前)。
那么,为了获得这种概率,我可以调用什么好的C#库来计算阶乘呢?我对阶乘计算中的所有惊人之处都不感兴趣,我只想要一种我可以操纵它的结果。在Math命名空间中似乎没有阶乘函数,因此出现了问题。
发布于 2009-09-30 02:38:36
你可以试试Math.NET --我还没有用过那个库,但是他们确实列出了阶乘和对数阶乘。
发布于 2009-09-30 02:37:20
已经有一个类似主题的previous question。有人在那里链接了Fast Factorial Functions网站,其中包括一些对有效算法的解释,甚至还有C#源代码。
发布于 2009-09-30 02:50:54
你想计算阶乘,还是二项式系数?
听起来你想要计算二项系数--特别是你提到11!/(7.3!)。
也许有一个库可以帮你做到这一点,但作为访问堆栈溢出的(可能)程序员,没有理由不自己编写一个。这并不是很复杂。
为了避免内存溢出,在删除所有公共因素之前,不要评估结果。
这个算法仍然需要改进,但是你已经有了一个好的算法的基础。为了获得最佳结果,需要将分母值拆分为它们的质因数。按照目前的情况,这将非常快地运行到n= 50。
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。
https://stackoverflow.com/questions/1495856
复制相似问题