#c #math #combinations
#c #математика #комбинации #c
Вопрос:
У меня есть небольшая программа. Я должен вычислить комбинацию с повторением.
Мой код:
int factorial(int a){
if (a<0)
return 0;
if (a==0 || a==1)
return 1;
return factorial(a-1)*a;
}
long int combinationWithRepetion(int n, int k){
long int a,b,wyn=0;
wyn=factorial(n (k-1))/(factorial(k)*factorial(n-1));
return wyn;
}
int main()
{
int k,n=0;
cout<<"Give n: ";
cin>>n;
cout<<"Give k: ";
cin>>k;
cout<<"combination With Repetion for n="<<n<<
" k="<<k<<".n Is equal to "<<combinationWithRepetion(n,k)<<endl;
return 0;
}
Для n = 9 и k = 6 в Wolfram alfa я получаю 3003, но в этой программе результат равен 44.
Для меня код в порядке.
Комментарии:
1. кому бы вы доверяли? Wolfram Alpha или ваш код?
2. @MitchWheat, очевидно, его собственный код!
3. @MitchWheat но что вы думаете о коде, может быть, я что-то упускаю?
Ответ №1:
С помощью n=9
и k=6
вы вычисляете, factorial(14)
что 87,178,291,200
из того, что переполнит 4 байта int
. Вам нужно использовать что-то вроде long long
, чтобы получить 8-байтовую int
формулу, если вы хотите использовать эту формулу.
Существуют лучшие формулы для вычисления биномиальных коэффициентов, которые не зависят от вычисления полных факториалов, а затем выполнения деления. Смотрите Биномиальный коэффициент в языках программирования, прямой метод (вместо использования рекурсии).
В C вы можете использовать:
int binomial(int N, int K) {
if( K > N - K )
K = N - K;
int c = 1;
for(int i = 0; i < K; i) {
c *= (N - i);
c /= (i 1);
}
return c;
}
Комментарии:
1. На платформе с 64-разрядными длинными версиями достаточно изменения в одной строке на
long long factorial(long long a)
, чтобы это заработало.2. @David Schwartz — Это сработает, но поскольку факториал растет так быстро, он будет переполняться для
factorial(21)
, поэтому я добавил ссылку на лучший способ вычисления биномиальных коэффициентов без предварительного вычисления факториалов.
Ответ №2:
Итак, вы вычисляете (n k-1), выбираете k . Заменяя n = 9, k = 6, получается 14choose6 (= 3003). Но 14! для представления требуется более 36 бит, но ваш int имеет только 32 бита. Лучшей реализацией было бы упростить n!/ ((n-k)!k!) до n(n-1)…(n-k 1) / k!. Или вы можете использовать pascal triangle.