C言語関係掲示板

過去ログ

No794 塾のクラス決定プログラム

[戻る] [ホームページ]
No.9943

教えて下さい
投稿者---悩める乙女(2003/10/22 22:18:15)


#include <stdio.h>
#define GAKU 6 /*学生数を定義*/
#define CLASS 2  /*クラスの数を定義*/
main()
{
   int GAKU;
   int CLASS;

  int g,c,choice[GAKU][CLASS],first[CLASS],second[CLASS];
/*学生数、クラス数、学生のクラスの希望を格納しておく、第一希望、第二希望*/

  for(g=0;g<GAKU;g++)

   {
     printf("Who are you? %d\n",g);/*どの学生かを表示*/

   for(c=0;s<CLASS;c++){
     printf("CLASS %d wa dainankibo?\n",c);/*どの学生が第何希望かを表示*/
     scanf("%d",&choice[g][c]);/*希望順位を表示*/
        printf("\nchoice[%d][%d] = %d\n",g,c,choice[g][c]);/*学生と希望順位の確認*/
   }
   }


  for(c=0;c<CLASS;c++)

  {  first[c]=0;/*第一希望を格納しておく場所*/
    second[c]=0;/*第二希望を格納しておく場所*/
   
  printf("Which class? %d\n",c);

   for(g=0;g<GAKU;g++){
     if (choice[g][c]==1)first[c]+=1;/*第一希望の人が一人いるごとに1を足す*/
else if (choice[g][c]==2)second[c]+=1;

   printf("first[%d]=%d\n",c,first[c]);/*第一希望が何人かを表示*/
   printf("second[%d]=%d\n",c,second[c]);

}
  for(s=0;c<CLASS;c++) {
        if(first[c]<=2)/*第一志望が二人以内なら*/
          for(g=0;g<GAKU;g++)
            if(choice[g][c]==1)
               printf("GAKU[%d]wa [%d] class\n",g,c);
          }/*その人たちを表示*/
      char amari;
        if(first[c]>3)/*三人を超えていたら*/
         for(g=0;g=GAKU;g++){
           amari=choice[g][c];
           printf("amari=%s\n",g);
         }


うちの塾のクラスを決めるのに、第3希望までとって、12人を4人ずつにわけたいのですが、まずは簡単なものから手を付けたのですが、分からなくなってしまいました(>_<)六人を三人ふたくらすに分けたいのですが、この先どうしたらいいのか頭を悩ませています。。。もし定員を超えたらその中からランダムに一人を選びその人を第二希望にまわしたいのですが。。。ここまではコンパイル時にエラーがなく、第一志望を表示するところまではいけました。その先がどうやっても望んでる結果がでなくて困ってます。どうかアドバイスの方よろしくお願いしますm(__)m

No.9945

Re:教えて下さい
投稿者---nop(2003/10/22 23:50:11)


>うちの塾のクラスを決めるのに、第3希望までとって、12人を4人ずつにわけたいのですが、まずは簡単なものから手を付けたのですが、分からなくなってしまいました(>_<)六人を三人ふたくらすに分けたいのですが、この先どうしたらいいのか頭を悩ませています。。。もし定員を超えたらその中からランダムに一人を選びその人を第二希望にまわしたいのですが。。。ここまではコンパイル時にエラーがなく、第一志望を表示するところまではいけました。その先がどうやっても望んでる結果がでなくて困ってます。どうかアドバイスの方よろしくお願いしますm(__)m

とりあえず、改行は適度に入れておいた方がよろしいかと。
で、質問の回答ですが、

まず、あなた自身がその作業を行う場合、
どの様な手順でその作業を行うのかを考えてみて下さい。
そして、その手順を紙に書くなり、
ワープロなどで打ち込むなどして文書化して見て下さい。

それが出来たら、その手順をそのままプログラムにして見て下さい。
そうすれば、後はコンパイル・リンクし実行してみて下さい。
そして、思い描いた手順通りに動いているか検証してみて下さい。
もし、思い通りに動かないのなら、どの様に違っているかを考えてみて下さい。
違いを見つけたら、その違う箇所を修正し、
もう一度コンパイル・リンクし実行して検証してみて下さい。

以上の事を繰り返せばプログラムが完成します。
おそらく、あなたが解らないのはプログラムではなく、
処理の方法(アルゴリズム)の方でしょう。

No.9952

Re:教えて下さい
投稿者---悩める乙女(2003/10/23 13:41:33)


確かにアルゴリズムも理解してるとはいえませんが、考えたアルゴリズムと入力する命令が一致させられないのです。今は、第一希望で決定の人を表示するところまでできているのですが、次に第一希望に漏れた人の中から適当に何人かを抜きだしあいてるクラスにいれたいのです。その際のrand関数の使い方や第一志望に漏れた人を指定するにはどうすればよいか、など頭が回らないのです。まだ、C言語をはじめて長くはないので、考え方がわからないんです。せめてヒントをもらえないでしょうか?

No.9958

Re:教えて下さい
投稿者---あかま(2003/10/23 20:31:28)


アドバイスをしようと思ってソースを読もうとしたんですけど、無理でした。
コンパイル通らないです。
たぶん閉じ括弧が2つか3つ足りないんですけど
インデントがいいかげん過ぎてどこに入れていいやら。
for(s=0;c<CLASS;c++) {
        if(first[c]<=2)/*第一志望が二人以内なら*/
          for(g=0;g<GAKU;g++)
            if(choice[g][c]==1)
               printf("GAKU[%d]wa [%d] class\n",g,c);
          }/*その人たちを表示*/
…以下省略

これとか恐ろしいインデントの付け方です。
最後の}が1つめのforの閉じ括弧なのか
2つめのforで{つけ忘れたのか、とか。なんだかいろいろ考えられます。
あと
for(g=0;g<GAKU;g++)

   {

とかなぜかforと{が離れているみたいなのも意味ないし読みにくいです。
とりあえず、コンパイルが通ってインデントがちゃんとついたやつをアップしてください。
でないと、プログラムのどこが分からないのか分からないんです。

No.9966

Re:教えて下さい
投稿者---RAPT(2003/10/24 00:12:42)


がんばって解析してみました。

> #define GAKU 6 /*学生数を定義*/
> #define CLASS 2  /*クラスの数を定義*/
> int GAKU;
> int CLASS;
こんなことしちゃいけません。
「#define CLASS 2」の後に2バイト文字の空白が含まれています。
また、#define解釈後、
int 6;
int 2;
とされ、コンパイルがされるため、コンパイルエラーです。

> for(c=0;s<CLASS;c++){
> for(s=0;c<CLASS;c++) {
sは宣言されていません。

> char amari;
> if(first[c]>3)/*三人を超えていたら*/
>   for(g=0;g=GAKU;g++){
>     amari=choice[g][c];
>     printf("amari=%s\n",g);
変数「amari」はchar型で、choice[g][c]はint型。
printf()の書式指定子で、%sは文字配列なのに、引数はchar型。

さらに、amariは、何のためにあるのでしょう?

> printf("first[%d]=%d\n",c,first[c]);/*第一希望が何人かを表示*/
> printf("second[%d]=%d\n",c,second[c]);
これらは、1段階ループの外側に出した方が良いでしょう。

> scanf("%d",&choice[g][c]);/*希望順位を表示*/
コメントが間違っています。‘表示’ではなく‘入力’でしょう。

> if(first[c]<=2)/*第一志望が二人以内なら*/
> if(first[c]>3)/*三人を超えていたら*/
first[c]==3 のときは処理は不要なのでしょうか?


一応、ソース解析のために修正したコードも掲載します。
# ローマ字表記は見づらいので漢字に。出力メッセージも減らした。
# 不明なところは適宜妄想で修正。
# 3人を超えていたら、のところは手付かず。


それにしても、なぜ、動くコードを掲載しないのでしょうか。
# 途中までは動いたのでしょう?
# あなたが掲載したコードでは、コンパイルすら通りません。


※最初のうちは、なるべく中カッコ{}を省略しないで書くようにしましょう。


#include <stdio.h>

#define GAKU 6  /* 学生数を定義 */
#define CLASS 2  /* クラスの数を定義 */

int main()
{
  int g;  /* 学生数用ループカウンタ */
  int c;  /* クラス数用ループカウンタ */
  int choice[GAKU][CLASS];  /* 学生のクラスの希望 */
  int first[CLASS] = {0};    /* 第一希望 */
  int second[CLASS] = {0};  /* 第二希望 */

  for(g = 0; g < GAKU; g++){
    /* どの学生かを表示 */
    printf("\n学生番号:%d\n", g);
    for(c = 0; c < CLASS; c++){
      printf("CLASS %d は第何希望? >>", c);  /* どの学生が第何希望かを表示 */
      scanf("%d", &choice[g][c]);        /* 希望順位を入力 */
      printf("\tchoice[%d][%d] = %d\n", g, c, choice[g][c]);  /* 学生と希望順位の確認 */
    }
  }

  for(c = 0; c < CLASS; c++){
    printf("クラス名:%d\n", c);
    for(g = 0; g < GAKU; g++){
      if (choice[g][c] == 1)
        first[c]++;    /* 第一希望の人が一人いるごとに1を足す */
      else if (choice[g][c] == 2)
        second[c]++;
    }
    printf("第一希望者の人数=%d\n", first[c]);  /* 第一希望が何人かを表示 */
    printf("第二希望者の人数=%d\n", second[c]);
  }

  for(c = 0; c < CLASS; c++) {
    if(first[c] <= 3){
      /* 第一志望が三人以内ならその人たちを表示 */
      for(g = 0; g < GAKU; g++){
        if(choice[g][c] == 1){
          printf("学生[%d]は [%d] クラス\n", g, c);
        }
      }
    }else{
      /* 三人を超えていたら */
      for(g = 0; g < GAKU; g++){
        if(choice[g][c] == 1){
          printf("amari=%d\n", choice[g][c]);
        }
      }
    }
  }
  return 0;
}


No.9995

Re:教えて下さい
投稿者---あかま(2003/10/25 01:45:35)


>がんばって解析してみました。
解析お疲れさまでした。

読んでみた結果、クラス人数が変わると色々と変更が必要そうなので全般的に書き直して見ました。
異様にネストが深くなったので読みづらいかと思いますが何とか読んでみてください。
1.第1希望の人数をカウント
2.第1を選んだ人がクラス容量以下なら決定、超えてたらランダムで選び出し
3.クラスすべて1,2を繰り返す
4.第2希望の人数カウント
5.クラス容量が余ってたら第2希望の人の中から選び出し。
6.これを第n希望まで繰り返し

ちなみにクラスの人数はGAKU/CLASSで出してます。
余りが出たらどうするんだとか考えてませんので〜。
#include <stdio.h>
#include <stdlib.h>

#define CLASS 3
#define GAKU 6

main(){
	int choice[CLASS][GAKU];
	int kettei[GAKU]={0};
	int class_cnt[CLASS]={0};
	int i,j,k,n;
	int cnt;
	srand(time(NULL));
	printf("希望入力(第1希望から第%d希望までクラス番号1-%dを入力してください)\n",CLASS,CLASS);
	for(i = 1;i <= GAKU;i++){
		printf("\n学生番号%d\n",i);
		for(j = 1;j <= CLASS;j++){
			printf("第%d希望:",j);
			scanf(" %d",&k);
			choice[k-1][i-1] = j;
		}
	}
	/*ここからクラス決定処理*/
	for(i = 1;i <= CLASS;i++){//第i希望の決定処理
		for(j = 0;j < CLASS;j++){//jクラスの
			if(class_cnt[j] < GAKU/CLASS){
				for(k = 0,cnt = 0;k < GAKU;k++){//第i希望者を数える
					if(choice[j][k] == i) cnt++;
				}
				printf("class_cnt%d,cnt%d\n",class_cnt[j],cnt);
				if(class_cnt[j]+cnt <= GAKU/CLASS){//(決定者+希望者)がクラス容量以内なら決定
					for(k = 0;k < GAKU;k++)
						if(choice[j][k] == i) kettei[k] = j+1,class_cnt[j]++;
					
				}
				else{//違うなら希望者の中からランダムで決定
					while(class_cnt[j] < GAKU/CLASS){
						n = rand()%GAKU;
						if(choice[j][n] == i && kettei[n] == 0) kettei[n] = j+1,class_cnt[j]++,choice[j][n] = 0,printf(" kita ");
					}
				}
			}
			
		}
		for(n = 0;n < GAKU;n++){
		printf("%d=%d  ",n+1,kettei[n]);
		
	}
	printf("\n");
	}
	
	printf("結果\n");
	for(i = 0;i < GAKU;i++){
		printf("学籍番号%dはクラス%d\n",i+1,kettei[i]);
	}
}


No.10167

ありがとうございます
投稿者---悩める乙女(2003/10/29 22:20:16)


あかまさん、RAPTさん、本当にありがとうございますm(__)mぼくはwindowsではなくマックのほうのターミナルでやっているもので日本語表示ができないのです・・・ほんとわかりづらくてすみません。マックからコピーペーストする際に括弧や文字に多少の変化があった模様です。しっかり確認しなくて申し訳ないです。ただ、文法的なところは私のミスです。すみません。。。これからまだまだ勉強しなければならないのでまたいきずまったときはよらしくお願いします!
頂いたプログラムを参考にさせていただきます!

No.10178

Re:教えて下さい
投稿者---悩める乙女(2003/10/30 04:48:12)


何度もすみませんm(__)m
あかまさんにお聞きしたいのですが、
if(choice[j][n] == i && kettei[n] == 0) kettei[n] = j+1,class_cnt[j]++,choice[j][n] = 0,printf(" kita ");はどういうことを意味しているのですかね?
#include <stdio.h>
#include <stdlib.h>
#define GAKU 6  /* 学生数を定義 */
#define CLASS 2  /* クラスの数を定義 */

int main()
{
  int g;  /* 学生数用ループカウンタ */
  int c;  /* クラス数用ループカウンタ */
  int choice[GAKU][CLASS];  /* 学生のクラスの希望 */
  int first[CLASS] = {0};    /* 第一希望 */
  int second[CLASS] = {0};  /* 第二希望 */

  for(g = 0; g < GAKU; g++){
    /* どの学生かを表示 */
    printf("\n学生番号:%d\n", g);
    for(c = 0; c < CLASS; c++){
      printf("CLASS %d は第何希望? >>", c);  /* どの学生が第何希望かを表示 */
      scanf("%d", &choice[g][c]);        /* 希望順位を入力 */
      printf("\tchoice[%d][%d] = %d\n", g, c, choice[g][c]);  /* 学生と希望順位の確認 */
    }
  }

  for(c = 0; c < CLASS; c++){
    printf("クラス名:%d\n", c);
    for(g = 0; g < GAKU; g++){
      if (choice[g][c] == 1)
        first[c]++;    /* 第一希望の人が一人いるごとに1を足す */
      else if (choice[g][c] == 2)
        second[c]++;
    }
    printf("第一希望者の人数=%d\n", first[c]);  /* 第一希望が何人かを表示 */
    printf("第二希望者の人数=%d\n", second[c]);
  }

  for(c = 0; c < CLASS; c++) {
    if(first[c] <= 3){
      /* 第一志望が三人以内ならその人たちを表示 */
      for(g = 0; g < GAKU; g++){
        if(choice[g][c] == 1){
          printf("学生[%d]は [%d] クラス\n", g, c);
        }
      }
    }else{
 
    }
  }
  return 0;
}



ランダムで抜き出し、他のクラスへ移動。それも希望の低い順に。
という風にしたいのですが。。。 前回のクラス分けだと二クラスなので満員なら違うクラスへ、ということができましたが、三クラスの場合はまた違った条件がひつようになってきますよね?できるだけ不公平のないようおにということを目標にしてるのですが、二クラスの三クラスだと与える条件が違うような気がして・・・できれば私のプログラムで与えた変数を利用して説明のほうをしていただきたいのですが。。。ほんと素人ですみません(>_<)






No.10204

Re:教えて下さい
投稿者---あかま(2003/10/30 15:53:24)


やっぱりわかりにくいですね。
わたしもコード書いてて混乱してたので、コードも混乱したものになってます。
すいません。

>ランダムで抜き出し、他のクラスへ移動。それも希望の低い順に。
希望の低い順にですか?
それだと生徒の希望がかなわないのでは。


1.私のコードでは、まず第1希望のクラスに生徒を割り当てます。
2.割り当てられた生徒がクラスの許容量以下の時はそれで決定します。
3.許容量を超えていた時はランダムで当選者を選び出し残りの人たちは落選です。
-------------
次は第2希望の選定で、
4.第2希望ですでに許容量いっぱいの教室を選んでしまっている人は自動的に落選です。
5.まだ余裕のある教室を選んでいる人は、第2希望の人が残った許容量以下なら自動的に決定
6.許容量を超えていた時は第2希望の人たちからランダムで当選者を選び出し残りの人たちは落選です。
-------------
これを第n希望(n=教室の数)まで繰り返して終了です。
これなら教室の数が変わっても処理が変わらないでしょう。


int kettei[GAKU]={0};
これは学生の決定済みのクラスを格納します。
kettei[0]に3
kettei[1]に2
が入っていたときは、学生番号1がクラス3に決定。学生番号2がクラス2決定という意味です。
決定してない時は0が入ってます。
学生番号と添え字が1ずれてます。これもよくないなーと後悔中です。
学生番号0って変だよなと思っただけなんですが。

int choice[CLASS][GAKU];
これは、悩める乙女さんのソースとはCLASSとGAKUが逆になっています。
choice[クラスkは][学籍番号iにとって] = j番目の希望;
という意味です。
ただし、添え字がやっぱり1つずれてます。クラス0って変だよなって思っただけなんです。
やっぱり分かりにくい(笑)。微妙にお酒飲んでました。すいません。

学生番号1の人の希望が
第1希望クラス3
第2希望クラス2
第3希望クラス1
の時は17行目のように

choice[3-1][1-1] = 1;
choice[2-1][1-1] = 2;
choice[1-1][1-1] = 3;

となるわけですね。-1はずれてる添え字を直しているのです。

class_cnt[CLASS];
はクラスの決定済み人数を格納しています。
class_cnt[0]==3;
の時はクラス1に3人決定してるという意味です。これも添え字1つずれてますので。

で、ご質問の
else{//違うなら希望者の中からランダムで決定
	while(class_cnt[j] < GAKU/CLASS){
		n = rand()%GAKU;
		if(choice[j][n] == i && kettei[n] == 0) kettei[n] = j+1,class_cnt[j]++,choice[j][n] = 0,printf(" kita ");
	}
}
の部分ですが、先に上げた手順の3.もしくは6.の部分ですね。

if(choice[j][n] == i && kettei[n] == 0)
第i希望の決定処理で、jクラスの処理の時。
適当に学生番号nを選んで、その人がi希望にjクラスを選んでいて、かつまだ決定してない(kettei[n] == 0)のとき

kettei[n] = j+1
その学生番号nをjクラスに決定。

class_cnt[j]++
クラスの決定人数が増えたので1進めます。

choice[j][n] = 0
これたぶんいらないっす。すんません。
決定済みのやつには0突っ込んどこうかなーとか考えたのをコードにしてたみたいです。

printf(" kita ");
うわぁぁぁぁ、これバグ取りのときに来てるかどうかみるために入れたやつです。
当然いらないです。すっげ恥ずかしい。

while(class_cnt[j] < GAKU/CLASS){
ということをクラスの人数がいっぱいになるまで繰り返す。ということですね。


ちなみによく"kita","mita","hanage","mimige"のどれかをコードに入れて確認してるんです。
hanageじゃなくてよかったーー。ってなんとなく自分の変なプログラム癖を白状してみるテスト。


ちなみに↓も決定した番号の順番を確認のためのコードですのでいりません。
for(n = 0;n < GAKU;n++){
		printf("%d=%d  ",n+1,kettei[n]);
}

相当長くなりましたがこんなところです。
すいません。いまも酒入ってます。こんな時間から…


No.10213

Re:教えて下さい
投稿者---RAPT(2003/10/31 00:15:56)


> if(choice[j][n] == i && kettei[n] == 0) kettei[n] = j+1,class_cnt[j]++,choice[j][n] = 0,printf(" kita ");

意味はともかく、これは以下のように書き換えるべきでしょう。

if(choice[j][n] == i && kettei[n] == 0){
  kettei[n] = j+1;
  class_cnt[j]++;
  choice[j][n] = 0;
  printf(" kita ");
}

読みにくい=保守性が低い=高品質なプログラムとは言えない。

また、相手は初心者なので、今後、へたに、
hoge[i] = 0, ++i, printf("%d : %d\n", i, hoge[i]);
とか書いたりしたら、面倒なことになってしまうでしょうから。


No.10286

Re:教えて下さい
投稿者---悩める乙女(2003/11/04 14:44:28)


わかりやすい説明ありがとうございます!かなり理解が深まってはきたのですが、まだ分からないのが、iとkです。iは学生数で、kは希望数ではないのですか?とちゅうからiとkが違うものをさしているようなきがしてならないのですが。。。いちを理解を深めるために自分でわかりやすいように工夫はしてみたのですが、今コンパイラが手元に無いため確かめることができませんでした。いちおう新しい定義とかを加え理解している範囲で変えてみました。
これで今の理解度がわかっちゃいますね(f..)
☆〜☆までの間のiとkがわからなくて困ってます(>_<)他にも理解違いなどがあれば指摘して欲しいのですが・・・プログラムの意味上あかまさんの見本と変わりはありません!それにしても独自のプログラミングの癖って面白いですね!!あれがkitaじゃなくhanageならすぐに確かめてる追加プログラムだってわかったのに(笑)すみません、できるだけ早めに返事いただければ光栄なのですが・・・頼んでる身分ですいませんm(__)m



#include <stdio.h>
#include <stdlib.h>

#define CLASS 3
#define GAKU 6
#define KIBOUSU 3 //第何希望までか
#define NINZU 3 //クラスの定員
main(){
	int choice[CLASS][GAKU];
	int kettei[GAKU]={0};
	int class_cnt[CLASS]={0};
	int g,c,kibou,n,i; //gは前のi,cは前のk,kibouはj
	int cnt;
	srand(time(NULL));
	printf("希望入力(第1希望から第%d希望までクラス番号1-%dを入力してください)\n",KIBOUSU,CLASS);
	for(g = 1;g <= GAKU;g++){
		printf("\n学生番号%d\n",g);
		for(kibou = 0;kibou <=KIBOUSU;kibou++){
			printf("第%d希望:",kibou);
			scanf(" %d",&c);
			choice[c][g] = kibou;
		}
	}
☆	for(i=0;i<CLASS;i++)
		for(kibou=0;kibou<KIBOUSU;kibou++){
			if(class_cnt[kibou] < NINZU){
				for(k = 0,cnt = 0;k < GAKU;k++){
					if(choice[kibou][k] == i) cnt++;
				}
				printf("class_cnt%d,cnt%d\n",class_cnt[kibou],cnt);
				if(class_cnt[kibou]+cnt <= NINZU){
					for(k = 0;k < GAKU;k++)
						if(choice[kibou][k] == g)
							{ kettei[k] = kibou+1;
							  class_cnt[kibou]++;}
				}
				else{
					while(class_cnt[kibou] < NINZU){
						n = rand()%GAKU;
						if(choice[kibou][n] == g && kettei[n] == 0){
  											kettei[n] = kibou+1;
  											class_cnt[kibou]++;
 											}
					}        ☆
				}
			}
			
		}
	printf("\n");
	}
	
	printf("結果\n");
	for(g = 0;g< GAKU;g++){
		printf("学籍番号%dはクラス%d\n",g,kettei[g]);
	}
}


No.10289

Re:教えて下さい
投稿者---あかま(2003/11/04 18:29:02)


>iは学生数で、kは希望数ではないのですか?とちゅうからiとkが違うものをさしているようなきがしてならないのですが。。。
間違いなく途中から違うもの指してます。なにも考えずに使わなくなった変数を再利用してたので。

とりあえず、悩める乙女さんの改造を見る限り、
1.よけいな-1とかを無くす
2.クラスの定員を加える
の方向かなと思いますので、その辺を直してみました。

#include <stdio.h>
#include <stdlib.h>

#define CLASS 3
#define GAKU 6
#define KIBOUSU 3 //第何希望までか
#define NINZU 3//クラスの定員
main(){
	int choice[CLASS+1][GAKU];//choice[0][*]は使わない。
	int kettei[GAKU]={0},ketteisu=0;//ketteisuはクラス決定済みの人数
	int class_cnt[CLASS+1]={0};//クラス番号は1からなのでclass_cnt[0][*]は使わない
	int g,c,kibou,n,i,k;//gは前のi,cは前のk,kibouはj
	int cnt;
	srand(time(NULL));
	printf("希望入力(第1希望から第%d希望までクラス番号1-%dを入力してください)\n",KIBOUSU,CLASS);
	for(g = 0;g < GAKU;g++){
		printf("\n学生番号%d\n",g);
		for(kibou = 1;kibou <= KIBOUSU;kibou++){
			printf("第%d希望:",kibou);
			scanf(" %d",&c);
			choice[c][g] = kibou;
		}
	}
	
	for(kibou=1;kibou<=KIBOUSU && ketteisu < GAKU;kibou++){
		for(i=1;i<=CLASS;i++){
			printf("class%d,class_cnt%d ",i,class_cnt[i]);
			if(class_cnt[i] < NINZU){
				for(k = 0,cnt = 0;k < GAKU;k++){
					if(choice[i][k] == kibou) cnt++;
				}
				
				if(class_cnt[i]+cnt <= NINZU){
					for(k = 0;k < GAKU;k++)
						if(choice[i][k] == kibou)
							{ kettei[k] = i;
							  class_cnt[i]++;
							  ketteisu++;
							  }
				}
				else{
					while(class_cnt[i] < NINZU && ketteisu < GAKU){
						n = rand()%GAKU;
						if(choice[i][n] == kibou && kettei[n] == 0){
  											kettei[n] = i;
  											class_cnt[i]++;
											ketteisu++;
 											}
					}
				}
			}
			
		}
	printf("\n");
	}
	
	printf("結果\n");
	for(g = 0;g< GAKU;g++){
		printf("学籍番号%dはクラス%d\n",g,kettei[g]);
	}
}


No.10304

Re:教えて下さい
投稿者---悩める乙女(2003/11/05 21:17:17)


あかまさん本当にありがとうございますm(__)m
かなりわかりやすかったです!このプログラムに関しては理解することができました。これからもう少し複雑にしていく上で行き詰まったらよろしくお願いします!かなりの時間をとらせてしまってすみませんでした。。。

No.10454

Re:教えて下さい
投稿者---悩める乙女(2003/11/12 03:10:51)


あかまさん、またまたすみませんm(__)m
こないだのプログラムを参考に理解を深め応用をきかせていこうと頑張っているのですが、2点わからないところがありまして・・・。まずは最初のほうにあるintで定義した={0}っていうのは配列を表しているのですか?よくどういうときに{}をつけるのかという疑問に頭をかかえるのです。なのでここでしっかり理解しておこうと思いまして。
もう1つは、前のプログラムについてなんですが、クラス数=希望数の時は間違いなくあのプログラムで走りますよね?でもクラス>希望数、つまり5クラスあるのに希望は3までしかとらない場合はうまく表示されないですよね?いろいろ考えてみてコードをかえてみたのですがうまくいかなくて・・・
もし、第三希望までに決まらなかった人は、定員を越えても第一希望になる。というプログラムを作りたいのですが最後のプリント命令の前にif分で「もしクラス=0なら第鬼望へ。」という文を入れるだけでは駄目なのですかね?前にあかまさんが提示してくれたプログラムでいいので参考例みたいのをいただけないでしょうか?それを理解した後で自分なりに作ってみたいと思うのですが。。。
お返事のほうよろしくお願いします!

No.10456

Re:教えて下さい
投稿者---あかま(2003/11/12 10:07:57)


{0}は配列の初期化です。詳しくは
http://www9.plala.or.jp/sgwr-t/c/sec02.html#s2-3
こちらをどうぞ。

プログラムですがすんごいバグもちでしたね。
ちゃんと動作確認しないとだめだ>ワタシ。

int choice[CLASS+1][GAKU]={0};

とりあえずchoiceを初期化してください。
これで変なクラスに登録されることがなくなります(たぶん)
初期のプログラムでは「クラス数=希望数」だったので、希望登録時に必ず上書きされていらなかったのです。
で、このままだとすべての希望に落ちた人が登録されないですね(クラス0のまま)。完全にバグです。
ということで「定員を越えても第一希望になる」という処理を加えましょう。

>プリント命令の前にif分で「もしクラス=0なら第鬼望へ。という文を入れるだけでは駄目なのですかね?
これであってるんですが、ワタシの書いたchoiceへの希望の格納の仕方が変でして。
↓をprintf("結果");の前に入れて下さい。

for(g = 0;g < GAKU;g++){
	if(kettei[g] == 0)
		for(c = 1;c <= CLASS;c++){//第1希望が何クラスか探さなくちゃいけない。
			if(choice[c][g] == 1){kettei[g] = c;break;}
		}
}


No.10471

Re:教えて下さい
投稿者---悩める乙女(2003/11/13 03:20:42)


ありがとうございます(^-^)/
何度かためしてみたんですが、無限ループに入り最後の人の入力が終っても結果の表示が起きないので明日も試してみます!おかげさまで理解が深まりバグを治すのも問題なくこなせるようになってきました!!プログラムが思った通りに動いた時の達成感は病みつきになりますねぇ〜 おやすみなさい