ページ 1 / 1
はじめまして!大学の課題なんですが、お願いします。
Posted: 2007年1月31日(水) 19:29
by ルーク
nCr において,n=0~6の全ての組み合わせについて求めるプログラムを作成しなさい。
表示例
0C0 = 1
1C0 = 1 1C1= 1
2C0 = 1 2C1 = 2 2C2 = 1
3C0 = 1 3C1 = 3 3C2 = 3 3C3 = 1
4C0 = 1 4C1 = 4 4C2 = 6 4C3 = 4 ・・・
・・・・
という問題なのですが、以下のように自分はプログラムを考えたのですが、
うまく実行できません。どこが間違ってるのでしょうか?
#include<stdio.h>
main(){
int n,r,nC0,a;
for(n=0;n<7;n++){
for(r=0;r<=n;r++){
nC0=1;
a=nC0;
a=(n-r+1)/r*a;
}
}
printf("%dC%d=%d\n",n,r,a);
}
Re:はじめまして!大学の課題なんですが、お願いします。
Posted: 2007年1月31日(水) 21:13
by box
> nCr において,n=0~6の全ての組み合わせについて求めるプログラムを作成しなさい。
まずは、nとrで制御する二重のループで、
下記のように出力するコードを書いてみてください。
等号の右にはnCrの値を出力しますが、その方法は別途考えるということで。
0C0=
1C0= 1C1=
2C0= 2C1= 2C2=
3C0= 3C1= 3C2= 3C3=
4C0= 4C1= 4C2= 4C3= 4C4=
5C0= 5C1= 5C2= 5C3= 5C4= 5C5=
6C0= 6C1= 6C2= 6C3= 6C4= 6C5= 6C6=
C言語はすごく苦手なので申し訳ありませんが、詳しくやり方を説明していただきたいのですが
Posted: 2007年2月03日(土) 14:21
by ルーク
すみません、二重ループ自体が苦手なのでわからないです。
あと、上から順序良く表示させる方法もわからなです。配列とか使うんですかね?
Re:C言語はすごく苦手なので申し訳ありませんが、詳しくやり方を説明していただきたいのですが
Posted: 2007年2月03日(土) 14:56
by box
> すみません、二重ループ自体が苦手なのでわからないです。
> あと、上から順序良く表示させる方法もわからなです。配列とか使うんですかね?
初めに投稿されたコードの、nとrに関する二重のfor文の書き方は正しいです。
ループの中身はちょっと問題ありでしたけど。
以下に示す回答の内容が理解できたら、ループの中身をどう書くかについて別途説明します。
なお、配列を使わなくても今回の問題は解けます。
私が前に回答した出力例を上から順に見てください。
先頭の行はnが0の場合です。
次の行はnが1の場合です。という具合にnが1ずつ増えていって、
一番下の行はnが6の場合です。
さて、今度は各行を右へ見ていきます。
rが0から始まって、どこまであるかというと、その行のnまであります。
よって、二重のfor文は、
nに関するfor文:0~6
各々のnについての、rに関するfor文:0~n
となります。最初の投稿で書かれたfor文の書き方の正しいことがわかります。
ここまではいいですか?
Re:C言語はすごく苦手なので申し訳ありませんが、詳しくやり方を説明していただきたいのですが
Posted: 2007年2月03日(土) 15:31
by 管理人
> すみません、二重ループ自体が苦手なのでわからないです。
苦手なのでしたら是非克服してください^^
苦手な分野があればプログラムの場合、
「概念を解説書である程度理解する」→「とにかく自分でプログラムを書いてみる」
の繰り返してマスターできるはずですよ♪
2重ループと言うのは以下の場合、今変数iとjがあったとき、iが1増える間にjは10増える、iが10増える間にjは100増えるといった関係が有ります。
for(i=0;i<10;i++){
for(j=0;j<10;j++){
//処理
}
}
では、このように書いたとき、出力はどうなるでしょうか?
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf("%d %d\n",i,j);
}
}
出力される結果を想像してみてください。
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10
1 0
1 1
1 2
(・・略・・)
こんな感じになるはずですね。では、2重ループを使って、y=xのグラフを書いてみましょう。
for(x=0;x<10;x++){
for(y=0;y<10;y++){
if(x==y)
printf("*");
else
printf(" ");
}
printf("\n");
}
座標がxが0~10、yが0~10(正確には9まで)の格子点は100個ありますね?
xが0の間にyは0~10を調べ、xが1の間にyは0~10をしらべ・・
つまりこの2重ループで100個全ての格子点が調べられます。
その時、yとxが同じ時に「*」を書き、そうでないときに、「 」(スペース)を書けば、
直線のグラフがかけると思いませんか?
ご自分で実際にコンパイルしてみてください。
苦手な分野があれば、それを使わないようにするのではなく、是非克服してみてください^^
返信遅れました。
Posted: 2007年2月05日(月) 19:09
by ルーク
はい、そこまでは、わかります。
Re:返信遅れました。
Posted: 2007年2月05日(月) 20:34
by box
nとrで制御する二重ループの中身の説明です。
例えば、nが3のときにはこんな行を出力する必要があるわけですね。
> 3C0= 3C1= 3C2= 3C3=
右辺の内容はさておくとして、左辺と等号までの内容をnとrを
使って書くと、どうなるでしょうか。
Cの左に来るのがnで、右に来るのがrですね。
出力するためのprintf関数の書き方は、例えばこんな感じです。
printf("%dC%d= ", n, r);
1行分出力し終わったら、つまりrに関するループを抜けたら、
改行します。
ここまではいいですか?
理解できたら、私boxが1月31日の21:13に投稿した出力例のための
コードを書いてみてください。
一応書きましたが、これであってますか??
Posted: 2007年2月07日(水) 18:27
by ルーク
#include<stdio.h>
main(){
int n,r;
for(n=0;n<7;n++){
for(r=0;r<=n;r++){
printf("%dC%d= ",n,r);
}
}
}
Re:一応書きましたが、これであってますか??
Posted: 2007年2月07日(水) 20:22
by box
サンプルコードを2つほど提示します。解読してみてください。
【1個目】
#include <stdio.h>
int ncr(int n, int r);
int kaijou(int n);
int main(void)
{
int n, r;
for (n = 0; n <= 6; n++) {
for (r = 0; r <= n; r++)
printf("%dC%d=%2d ", n, r, ncr(n, r));
printf("\n\n");
}
return 0;
}
/* nCrを計算する関数 */
int ncr(int n, int r)
{
return kaijou(n) / kaijou(r) / kaijou(n-r);
}
/* 階乗を計算する関数 */
int kaijou(int n)
{
if (n == 0)
return 1;
else
return n * kaijou(n-1);
}
【2個目】
#include <stdio.h>
int ncr(int n, int r);
int main(void)
{
int n, r;
for (n = 0; n <= 6; n++) {
for (r = 0; r <= n; r++)
printf("%dC%d=%2d ", n, r, ncr(n, r));
printf("\n\n");
}
return 0;
}
/* nCrを計算する関数(パスカルの三角形) */
int ncr(int n, int r)
{
if (r == 0 || n == r)
return 1;
else
return ncr(n-1, r-1) + ncr(n-1, r);
}
丁寧な返信どうもありがとうございます。
Posted: 2007年2月07日(水) 23:53
by ルーク
わかりました!◎
自分は、nCr=(n-r+1)/r*nCr-1 という式を用いて、
ループを回した感じでしあげたいのですが、その場合はどうしたら
よろしいのですか??
Re:丁寧な返信どうもありがとうございます。
Posted: 2007年2月08日(木) 09:16
by box
> 自分は、nCr=(n-r+1)/r*nCr-1 という式を用いて、
考え方はこれまでのサンプルと同じです。
使いたい式をそのまま関数化します。
#include <stdio.h>
int ncr(int n, int r);
int main(void)
{
int n, r;
for (n = 0; n <= 6; n++) {
for (r = 0; r <= n; r++)
printf("%dC%d=%2d ", n, r, ncr(n, r));
printf("\n\n");
}
return 0;
}
int ncr(int n, int r)
{
if (r == 0 || n == r)
return 1;
else
return ncr(n, r-1) * (n - r + 1) / r;
}
Re:丁寧な返信どうもありがとうございます。
Posted: 2007年2月08日(木) 09:40
by box
> 自分は、nCr=(n-r+1)/r*nCr-1 という式を用いて、
別のサンプルコードです。
これがいちばんシンプルかも。
#include <stdio.h>
int main(void)
{
int n, r;
for (n = 0; n <= 6; n++) {
for (r = 0; r <= n; r++) {
int ncr;
if (r == 0 || n == r)
ncr = 1;
else
ncr = ncr * (n - r + 1) / r;
printf("%dC%d=%2d ", n, r, ncr);
}
printf("\n\n");
}
return 0;
}
どうもありがとうございます!!。
Posted: 2007年2月09日(金) 00:29
by ルーク
これで宿題が解決しました。
また、知識も深まりました。ホントにどうもありがとうございました。
また、お世話になることがありましたらよろしくおねがいします◎