二項係数

二項係数を求めるプログラムを、再帰を使ったのと、公式を使ったの二通りで作ってみた。

long product_n2k(long n,long k){
    if (n == 0){
        return 1;
    } else if (n == k) {
        return n;
    }else {
        return n * product_n2k(n - 1, k);
    }
}

long bi_coefficient(long n, long k){
    if (k == 0)
        return 1;
    else
        return product_n2k(n, n - k + 1) / product_n2k(k, 1);
}

公式\Pi^{k-1}_{i=0}(n-i)/k!を使ったバージョン。product_n2kはnからkまでの数をかけた値を返す関数。ここで再帰つかってるじゃんという話もあります。k = 0のときどうすればいいのか分からなくなったので、場合分けしました。if文使わないでうまいこと書けないのかなあ。

long bi_coefficient_r(long n,long k){
    if (n == 0 || k == 0 || n == k){
        return 1;
    }else {
        return bi_coefficient_r(n-1,k-1) + bi_coefficient(n-1,k);
    }
}

パスカルの三角形的に再帰使って書いたバージョン。うーん、簡潔だ……。
(n k) = (n n-k)になることを使ったら計算量が減る気がする。

int main_b(){
    long i,j;
    long a,ar;
    for(i = 0; i < 20 ;i++) {
        for(j = 0; j <= i; j++) {
            cout << i << "," << j << ":";
            cout << (a = bi_coefficient(i, j)) << " ";
            cout << (ar = bi_coefficient_r(i, j)) << " ";

            if ( a == ar) {
                cout << ": OK\n";
            }else{
                cout << ": NG\n";
            }
        }
    }
}

でちゃんと同じ値になるかチェックしてみた。n=12までは良いんですが、n=13ぐらいから、答えがマイナスになったりして、合わなくなってくる。計算途中で大きすぎる値が出るのかなあ。
あとn=100やってみたら、途中でFloating Point Exceptionはいて終了。階乗の力すごい。