- ベストアンサー
整数型配列と2次元文字型配列の入れ替え方
以下のプログラムを実行結果のように作りたいのですがexchange_numberの中身の書き方(配列の入れ替え方)が分らないので教えて下さい。 #include<stdio.h> #define M 10 #define N 5 void sort_score(int score_cpy[M]); int linear_search(int score_cpy[M],int key); void exchange_number(int order[M],char number[M][N]); int no; int main(void) { int i,number[M][N],score[M],score_cpy[M],order[M]; printf("人数を入力して下さい:"); scanf("%d",no); ("学生番号と平均点を入力して下さい。"); for(i=0;i<M;i++){ printf("学生番号:"); scanf("%s",&number[i][N]); printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<=M;i++) score_cpy[i]=score[i]; sort_score(score_cpy); for(i=0;i<M;i++){ order[i]=linear_search(score_cpy,score[i]); } exchange_number(order,number); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++) printf("学生番号 :%s %d点\n",number[i],score_cpy[i]); return 0; } void sort_score(int score_cpy[M]) { int i,j,score; for(j=0;j<no-1;j++){ for(i=no-1;i>0;i--){ if(score_cpy[i-1]<score_cpy[i]){ score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int score_cpy[M],int key) { int i; for(i=0;i<no;i++){ if(score_cpy[i]==key){ return i; } } return -1; } void exchange_number(int order[M],char number[M][N]) {?} ちなみに実行結果は以下の通りです。 人数を入力して下さい:10 学生番号と平均点を入力して下さい。 学生番号:y3051 得点:85 学生番号:y3052 得点:65 学生番号:y3053 得点:75 学生番号:y3054 得点:63 学生番号:y3055 得点:95 学生番号:y3056 得点:68 学生番号:y3057 得点:80 学生番号:y3058 得点:90 学生番号:y3059 得点:83 学生番号:y3060 得点:70 得点の高い順に並び替えて表示します 学生番号:y3055 95 点 学生番号:y3058 90 点 学生番号:y3051 85 点 学生番号:y3059 83 点 学生番号:y3057 80 点 学生番号:y3053 75 点 学生番号:y3060 70 点 学生番号:y3056 68 点 学生番号:y3052 65 点 学生番号:y3054 63 点 プログラム中で間違えがありましたら指摘して頂けると幸いです。それで良いお待ちしております。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
いやいや、ひねくれた例題ですね。間違い箇所が多く見られ、実際にまだコンパイルはされていないようですよね。レポートは明日までとのことですので参考に...。 ここでの一番の問題は、なぜ「void exchange_number(int order[M],char number[M][N]);」関数を作らなければいけないかの疑問です。結果は、ソート降順に行われることから、次の for() ループでは order[i]=linear_search(score_cpy,score[i]); の学生番号順にソート順番が何番であるかを求めるのではなく、 order[i]=linear_search(score,score_cpy[i]); のソート結果に対して何番の学生番号が該当するのかのプログラム内容とならなければなりません。事例ではわざとかく乱させて、ご要望の関数を作らないとさも答えが出ないような内容になっています。例題は考えられています。 回答は、平均点が重なってもきちんと表示されるように「 signed char flag[M];」を追加してみました。したがって、要望の関数は不要です。とりあえず、動くかどうか試してみてください。 #include<stdio.h> #define M 10 #define N 8 // 余裕を持たせましょう。 void sort_score(int score_cpy[]); int linear_search(int key, int score[], signed char flag[]); int no; int main(void) { int i,score[M],score_cpy[M],order[M]; char number[M][N]; signed char flag[M]; printf("人数を入力して下さい:"); scanf("%d",&no); ("学生番号と平均点を入力して下さい。"); for(i=0;i<no;i++) { printf("学生番号:"); scanf("%s",number[i]); printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<no;i++) { score_cpy[i]=score[i]; flag[i] = 0; } sort_score(score_cpy); for(i=0;i<no;i++) order[i]=linear_search(score_cpy[i], score, flag); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++) printf("学生番号 :%s %d点\n", number[order[i]],score_cpy[i]); return 0; } void sort_score(int score_cpy[]) { int i,j,score; for(j=0;j<no-1;j++) { for(i=no-1;i>j;i--) { if(score_cpy[i-1]<score_cpy[i]) { score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int key,int score[], signed char flag[]) { int i; for(i=0;i<no;i++) { if(key == score[i] && flag[i] == 0) { flag[i] = -1; // 重複を回避する break; } } return i; }
その他の回答 (4)
- cyacya2000
- ベストアンサー率54% (39/71)
またまたすみません。実行結果を見ると学生番号にはyという文字が入っているので文字列ですね。ということはnumberは文字型配列にしないといけませんね。Mが学生数で、Nは学生番号の最大数だったのでしょうか? プログラムだけ見て実行結果に注意をしていませんでした。ごめんなさい。 でも、前回のサンプルプログラムが参考になると思います。これを参考に自分で少し考えてみることをお勧めします。
- cyacya2000
- ベストアンサー率54% (39/71)
すみません。Mは使用しないといっておいて、サンプルにはMを残してしまいました。このままでも動くと思いますが、MはNにするつもりでした。
- cyacya2000
- ベストアンサー率54% (39/71)
このプログラムに関して3点ほど質問があります。 質問1 なぜ学生番号を%Sで読み込む必要があるのか? 質問2 なぜnumber配列は2次元である必要があるのか? 質問3 define定義されているMとNはどんな意味を持つのか? で、次のように勝手に解釈して作ったプログラムを以下に示します。 いろいろ突っ込みが入るかもしれませんが参考にして下さい。 解釈1 学生番号は%dで読み込む 解釈2 numberは1次元配列にする 解釈3 Mは使用しない。Nは学生の最大人数 <プログラム> オリジナルから修正を加えた部分はコメントを入れておきました。 #include<stdio.h> #define M 10 #define N 5 void sort_score(int score_cpy[M]); int linear_search(int score_cpy[M],int key); void exchange_number(int order[M],int number[M]); //numberはint型です。 int no; int main(void) { int i,number[M],score[M],score_cpy[M],order[M];//numberを2次元配列にするのはなぜ? printf("人数を入力して下さい:"); scanf("%d",&no);//&がない printf("学生番号と平均点を入力して下さい。");//printfがない for(i=0;i<no;i++){ //no回くりかえせばいい printf("学生番号:"); scanf("%d",&number[i]);//%dでよいのでは?Nしか確保していないのにNにいれてはダメ //そもそも2次元配列にする意味が解らない printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<=M;i++) score_cpy[i]=score[i]; sort_score(score_cpy); for(i=0;i<M;i++){ order[i]=linear_search(score_cpy,score[i]); } exchange_number(order,number); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++) printf("学生番号 :%d %d点\n",number[i],score_cpy[i]);//numberはintなので%sでなく%d return 0; } void sort_score(int score_cpy[M]) { int i,j,score; for(j=0;j<no-1;j++){ for(i=no-1;i>0;i--){ if(score_cpy[i-1]<score_cpy[i]){ score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int score_cpy[M],int key) { int i; for(i=0;i<no;i++){ if(score_cpy[i]==key){ return i; } } return -1; } void exchange_number(int order[M],int number[M]){ int i; int tmp[M]; //numberを全てコピーして for(i=0;i<M;i++){ if(order[i]==-1) break; tmp[i]=number[i]; } //該当箇所にセット for(i=0;i<M;i++){ if(order[i]==-1) break; number[order[i]]=tmp[i]; } }
- asuncion
- ベストアンサー率33% (2127/6289)
学生番号と試験点数をメンバーに持つ構造体の配列を定義します。 読み込んだデータを前項の配列に格納します。 配列の要素(試験点数)どうしを比較し、点数の降順になるよう、 必要に応じて配列の要素(学生番号と試験点数)を入れ替えます。
補足
申し訳ないのですが、C言語については初心者並みですので、exchange_numberの中身を書いて頂けるとうれいしいのですが・・・お願い致します。
補足
こちらの説明不足で何度もお答えさせてしまい申し訳ありません。 この回答の通り、numberは学生を表す文字型配列でMが学生数、Nが学生番号の最大数です。この場合で考えると、文字型なので1文字ずつ入れ替えるように作るんですかね?明日までに、レポートとして提出しなければならないので、出来れば前回のサンプルプログラムを書きなおして欲しいのですが・・・宜しくお願い致します。