calculate n choose k

Let's talk about algorithms!

Moderator: Board moderators

Post Reply
Maniac
Experienced poster
Posts: 105
Joined: Tue Oct 14, 2003 3:24 pm
Location: Utrecht, Holland

calculate n choose k

Post by Maniac »

I was wondering whether there is a smart way of calculating n choose m without having the possibility of an overflow during the calculation (when it's given that the result is within bounds).

I always use this method

[java]static long choose(int n, int m) {
if(m > n/2) return choose(n, n-m);
long t = 1;
for(int i=1; i<=m; i++)
t = (t * (n-m+i))/i;
return t;
}[/java]

but this could overflow because I multiply before I divide. Is there a way to avoid an overflow without factorizing n and m?
SilentStrike
New poster
Posts: 22
Joined: Fri Jan 04, 2002 2:00 am

Post by SilentStrike »

This works. The computation takes n^2 time, but you only have to do it once, and I doubt you need to store that many.

[cpp]
#include <iostream>
using namespace std;
static long choose(int n, int m) {
if(m > n/2) return choose(n, n-m);
long t = 1;
for(int i=1; i<=m; i++)
t = (t * (n-m+i))/i;
return t;
}

int choose_tbl[100][100];

long choose2(int n, int m) {
int &ret = choose_tbl[n][m];
if (ret != -1) return ret;
ret = choose2(n-1, m) + choose2(n-1, m-1);
return ret;
}

int main() {
for (int i = 0; i < 100; ++i)
for (int j = 0; j < 100; ++j)
if (j < i) choose_tbl[j] = -1;
else choose_tbl[j] = 1;


for (int i = 0; i < 100; ++i) choose_tbl[0] = choose_tbl = 1;
for (int i = 0; i < 12; ++i) {
for (int j = 0; j < 12; ++j)
if (choose2(i, j) != choose(i, j))
cout << i << "\t" << j << "\t" << choose(i, j) << "\t" << choose2(i, j) << "\n";
//cout << i << "\t" << j << "\t" << choose2(i, j) << "\n";
}
}
[/cpp]
titid_gede
Experienced poster
Posts: 187
Joined: Wed Dec 11, 2002 2:03 pm
Location: Mount Papandayan, Garut

Post by titid_gede »

a little hint : prime factorization :)
Kalo mau kaya, buat apa sekolah?
misof
A great helper
Posts: 430
Joined: Wed Jun 09, 2004 1:31 pm

Post by misof »

titid_gede wrote:a little hint : prime factorization :)
a little hint... next time read the whole post you are replying to :P
marian
New poster
Posts: 30
Joined: Sun Oct 27, 2002 4:01 pm
Contact:

Re: calculate n choose k

Post by marian »

Maniac wrote:but this could overflow because I multiply before I divide. Is there a way to avoid an overflow without factorizing n and m?
You can use GCD. When computing (A*B)/C, let G=GCD(A,C) then

(A*B)/C = (A/G) * (B/(C/G)).
Maniac
Experienced poster
Posts: 105
Joined: Tue Oct 14, 2003 3:24 pm
Location: Utrecht, Holland

Post by Maniac »

Yes, your right. That would certainly avoid the overflow. Thanks!
Post Reply

Return to “Algorithms”