プロが教えるわが家の防犯対策術!

キーボードから二つの正の整数n,r を入力し,組み合わせの数nCr を計算して画面表示するプログラムを作成せよ.ただし,組み合わせの数を計算する関数のプロトタイプをint combination( int, int )とし,my_scanf()をキーボードから二つの正の整数n,r を入力する関数,kaijo() を階乗を求めるプログラムとする.

という問題なんですが

#include <stdio.h>
int my_scanf(void){
int n;
do{
scanf("%d",&n);
}while(n <= 0);
return n;
}
int kaijo(int m){
int i,x = m;
for(i=1;i<m;i++){
x *= i;
}
return x;
}
int combination( int m, int w){
int ncr;
ncr = m/w;
return ncr;
}
int main (void){
int pos,sum_n,sum_r,answer;

printf("n = ");
pos = my_scanf();
sum_n = kaijo(pos);

printf("r = ");
pos = my_scanf();
sum_r = kaijo(pos);

answer = combination(sum_n,sum_r);

printf("nCr = %d",answer);
return(0);
}

結果的にはn!/r!を求めるプログラムに・・・・。
combination関数内を書き直せばいいのでしょうか?

A 回答 (9件)

すいません間違えました。


nCrを階乗を使ってあらわすと
nCr = nPr / r!
nPm = n! / (n-r)!

プログラムに詳しくないので
良い例ではないと思いますが
少し変えさせていただきました。

#include <stdio.h>
int my_scanf(void){
int n;
do{
scanf("%d",&n);
}while(n <= 0);
return n;
}
int kaijo(int m){
int i,x = m;
for(i=1;i<m;i++){
x *= i;
}
return x;
}
int combination( int n, int r){
int ncr;
ncr = kaijo(n) / kaijo(n-r) / kaijo(r);
return ncr;
}
int main (void){
int n,r,answer;

printf("n = ");
n = my_scanf();

printf("r = ");
r = my_scanf();

answer = combination(n,r);

printf("nCr = %d",answer);
return(0);
}
    • good
    • 1
この回答へのお礼

nC rの定義がn!/n!(n-r)!でしたね。ありがとうございました。参考にします。

お礼日時:2007/11/06 20:45

"Combination 関数" で検索する。



参考URL:http://edu.net.c.dendai.ac.jp/ad/1/2005/1/index. …
    • good
    • 0

>#7


n = 5
r = 5

#r = 0でもOKなはず。

#俺?オーバーフローとかの検出方法とか知らないんで書けない。
    • good
    • 0

nCrを階乗を使ってあらわすと


nCr = nPm / m!
nPm = n! / (n-m)!

という事を書けば良いんじゃないですかね?
間違ってたらすいません。
    • good
    • 0

n!/r! ではなくて、どういう式になるのが


正しいのかはわかっているのでしょうか?
それがわかっていれば、悩む必要は無い気がします。

現状では、
sum_nを求めるのにも
sum_rを求めるのにも
同じ関数kaijo()を使用しているので、
n!/r! を求めてしまうのは当然だと思うのですが・・・
    • good
    • 0

scanf()の戻り値をチェックするとよいと思います。


戻り値には読み込んだ変数の数が返されます。

数字の変わりにアルファベットを入力したら無限ループになるような気がします。
    • good
    • 0

仕様に従えば、combination内で階乗するべきでは?



ncr = kaijo(m)/kaijo(w);

として、main関数内のkaijo()は不要。

------------------------------------------------
>my_scanf()をキーボードから二つの正の整数n,r を入力する関数

これも仕様に忠実に作るなら、
下記のような関数にするべきですね。

void my_scanf(int *n, int *r){
/*
 この関数内で、n と r 両方に入力する。
 scanfの記述が少し難しくなるかな。
 n と r がポインタなので、下記はNGです。
 scanf("%d %d", &n, &r);
 ポインタの扱いに慣れていないと難しいかも。
 課題ぽいので、答えは書きません。考えてみてください。
*/
}
------------------------------------------------
もう1つ、細かい指摘をすれば、

for(i=1;i<m;i++){
x *= i;
}

ここにも、ほんの少し無駄がありますよ。
    • good
    • 0

#1です。


因みに、私なら
int combination( int m, int w){
return m/w;
}
にすると思います。
また、
「my_scanf()をキーボードから二つの正の整数n,r を入力する関数」
ということなので、my_scanf()を2回呼ぶのではなく、my_scanf()で2値の入力が完結するように変更すると思います。
    • good
    • 0

質問のプログラムで何か不都合があるのでしょうか?



私の環境ではうまく動いているのですが…。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!