Прежде всего, я отмечаю, что вы пытаетесь вычислить биномиальный коэффициент, поэтому назовем его так.
Вот несколько способов сделать это.Если вы используете BigInteger, вам не нужно беспокоиться о переполнении:
Первый метод: используйте factorial:
static BigInteger Factorial(BigInteger n)
{
BigInteger f = 1;
for (BigInteger i = 2; i <= n; ++i)
f = f * i;
return f;
}
static BigInteger BinomialCoefficient(BigInteger n, BigInteger k)
{
return Factorial(n) / (Factorial(n-k) * Factorial(k));
}
Второй метод: используйте рекурсию:
static BigInteger BinomialCoefficient(BigInteger n, BigInteger k)
{
if (n == 0) return 1;
if (k == 0) return 0;
return BinomialCoefficient(n-1, k-1) + BinomialCoefficient(n-1, k)
}
Thisметод, однако, не быстрый, если вы не запомните результат.
Метод третий: будьте более умны в отношении минимизации количества умножений и раннего деления.Это позволяет сохранять малые числа:
static BigInteger BinomialCoefficient(BigInteger n, BigInteger k)
{
// (n C k) and (n C (n-k)) are the same, so pick the smaller as k:
if (k > n - k) k = n - k;
BigInteger result = 1;
for (BigInteger i = 1; i <= k; ++i)
{
result *= n - k + i;
result /= i;
}
return result;
}
Так, например, если вы вычисляли (6 C 3) вместо вычисления (6 x 5 x 4 x 3 x 2 x 1) / ((3 x 2)x 1) x (3 x 2 x 1)), вы вычисляете (((4/1) * 5) / 2) * 6) / 3, что по возможности сохраняет небольшие числа.