ページ 1 / 1
順位について
Posted: 2017年7月24日(月) 22:52
by しき
http://dixq.net/forum/viewtopic.php?f=3&t=19425
からの継続です。
「学生について出席番号と試験の成績が入力として与えられるときに,成績に順位 をつけ,その順位と出席番号と成績を,成績が良い順に出力するプログラムを作成せよ。ただし,同じ成績の者は同じ順位とし,順位が i 番の者が x 人ならば 次の成績の者の順位は i+x であるとする。また,成績が同じ場合には,出席番号の小さい方を先に出力するものとする」
この問題を解いているのですが「同じ成績の者は同じ順位とし,順位が i 番の者が x 人ならば 次の成績の者の順位は i+x であるとする」という箇所の解き方が分かりません。現在は簡単に順位をつけるといった状態になっています。どこに何を入れたらよいのか教えてください。
コード:
#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
#define RANK 30
int main()
{
int d[MAXDATA];
int X;
int a[ATTEND];
int b[RANK];
int i, j, k;
int tmp;
printf("今回集計する人数を入力="); scanf("%d",&X);
for (i = 0; i < X; i++){
printf("試験の成績を入力してください。\n");
printf("%d 人目:",i+1);
scanf("%d", &d[i]);
printf("この人の出席番号を入力してください。\n");
scanf("%d" ,&a[i]);
}
printf("今回の試験順位(昇順)\n");
for(i=0;i < X-1; i++){
j=i;
for(k=i+1; k < X; k++){
if(d[j]<d[k]){ j = k; }
}
tmp = d[j];
d[j] = d[i];
d[i] = tmp;
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
for (i = 0; i < X; i++) {
printf("%d位.", i+1); printf("出席番号:%d ", a[i]); printf("点数:%d\n", d[i]);
}
}
Re: 順位について
Posted: 2017年7月24日(月) 23:20
by みけCAT
順位を記録する変数とその初期化を出力部分のループの前に追加し、
出力部分のループに「上の人が存在し、かつこの人の成績が上の人と違ったら、かつその時に限り順位を記録する変数を更新する」処理と、
順位を記録する変数を出力する処理を追加するといいでしょう。
動作イメージ
コード:
添字 順位 成績
0 1 100 ← 上の人が存在しないので、順位を更新しない (初期化したまま)
1 2 90 ← 上の人と成績が違うので、順位を添字+1に更新する
2 2 90 ← 上の人と成績が同じなので、順位を更新しない
3 2 90 ← 上の人と成績が同じなので、順位を更新しない
4 5 50 ← 上の人と成績が違うので、順位を添字+1に更新する
5 6 40 ← 上の人と成績が違うので、順位を添字+1に更新する
Re: 順位について
Posted: 2017年7月24日(月) 23:22
by kinokawa
b[RANK]に順位を入れて、上位の成績と同じならば
順位(b[RANK]の内容)をコピーすればいけそうな気がします
Re: 順位について
Posted: 2017年7月25日(火) 10:05
by しき
みけCATさん、kinokawaさん返信ありがとうございます。
今回はみけCATさんの方法をとらせていただきました。
ソースコードは前回投稿した記事をもとに少しだけ変更しました。
以下が実行結果になりますが1位が表示されないのはなぜでしょうか・・また実行結果2の方では正常に作動しないことも疑問です・・
実行結果1
------------------------------------------
今回集計する人数を入力=5
試験の成績を入力してください。
1 人目:100
この人の出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:80
この人の出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:80
この人の出席番号を入力してください。
3
試験の成績を入力してください。
4 人目:90
この人の出席番号を入力してください。
4
試験の成績を入力してください。
5 人目:50
この人の出席番号を入力してください。
6
今回の試験順位(昇順)
0位.出席番号:1 点数:100
2位.出席番号:4 点数:90
3位.出席番号:3 点数:80
3位.出席番号:2 点数:80
5位.出席番号:6 点数:50
------------------------------------------
実行結果2
------------------------------------------
今回集計する人数を入力=3
試験の成績を入力してください。
1 人目:100
この人の出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:100
この人の出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:20
この人の出席番号を入力してください。
3
今回の試験順位(昇順)
0位.出席番号:1 点数:100
1位.出席番号:2 点数:100
2位.出席番号:3 点数:20
------------------------------------------
コード:
include <stdio.h>
#define MAXDATA 100
int main()
{
int d[MAXDATA];
int X;
int a[MAXDATA];
int b[MAXDATA];
int i, j, k;
int tmp;
printf("今回集計する人数を入力="); scanf("%d",&X);
if(X >= MAXDATA){
do{
printf("もう一度生徒数を入力してください。");
scanf("%d", &X);
}while(X > MAXDATA);
}
for (i = 0; i < X; i++){
printf("試験の成績を入力してください。\n");
printf("%d 人目:",i+1);
scanf("%d", &d[i]);
printf("この人の出席番号を入力してください。\n");
scanf("%d" ,&a[i]);
}
printf("今回の試験順位(昇順)\n");
for(i=0;i < X-1; i++){
j=i;
for(k=i+1; k < X; k++){
if(d[j]<d[k]){ j = k; }
}
tmp = d[j];
d[j] = d[i];
d[i] = tmp;
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
for (i=1; i<=X; i++){ //追加したもの
b[i] = 1;
}
for (i=2; i<=X; i++) {
for (j=1; j<=i-1; j++) {
if(d[j] > d[i]) b[i]++;
if(d[j] < d[i]) b[j]++;
}
}
for (i = 0; i < X; i++) {
printf("%d位.", b[i]); printf("出席番号:%d ", a[i]); printf("点数:%d\n", d[i]);
}
}
Re: 順位について
Posted: 2017年7月25日(火) 12:02
by しき
試行錯誤するうちにできました。しかしこれで完成ではなく「また,成績が同じ場合には,出席番号の小さい方を先に出力するものとする」という問題が残ります。これも何回か挑戦しているのですが解決策が見つかりません・・。どうかよろしくお願いします。
コード:
include <stdio.h>
#define MAXDATA 100
int main()
{
int d[MAXDATA];
int X;
int a[MAXDATA];
int b[MAXDATA];
int i, j, k;
int tmp;
printf("今回集計する人数を入力="); scanf("%d",&X);
if(X >= MAXDATA){
do{
printf("もう一度生徒数を入力してください。");
scanf("%d", &X);
}while(X > MAXDATA);
}
for (i = 0; i < X; i++){
printf("試験の成績を入力してください。\n");
printf("%d 人目:",i+1);
scanf("%d", &d[i]);
printf("この人の出席番号を入力してください。\n");
scanf("%d" ,&a[i]);
}
printf("今回の試験順位(昇順)\n");
for(i=0;i < X-1; i++){
j=i;
for(k=i+1; k < X; k++){
if(d[j]<d[k]){ j = k; }
}
tmp = d[j];
d[j] = d[i];
d[i] = tmp;
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
for (i = 0; i < X; i++) {
b[i] = 1;
}
for (i=1; i<=X; i++) {
for (j=0; j<=X-1; j++) {
if(d[i] <d[j]){
b[i]++;
}
}
}
for (i = 0; i < X; i++) {
printf("%d位.", b[i]); printf("出席番号:%d ", a[i]); printf("点数:%d\n", d[i]);
}
}
Re: 順位について
Posted: 2017年7月25日(火) 12:40
by かずま
しき さんが書きました:しかしこれで完成ではなく「また,成績が同じ場合には,出席番号の小さい方を先に出力するものとする」という問題が残ります。
if(d[j]<d[k]) を
if (d[j] < d[k] || d[j] == d[k] && a[j] > a[k]) に
すればよいでしょう。
それから、みけCATさんの方法は、配列 b は使わないと思います。
上の人と成績が同じ場合は順位を更新しない。それだけです。
次のプログラムを見てください。
コード:
#include <stdio.h>
#define MAXDATA 100
int main(void)
{
int d[MAXDATA];
int X;
int a[MAXDATA];
int i, j, k;
int tmp;
printf("今回集計する人数を入力=");
while (1) {
scanf("%d", &X);
if (X <= MAXDATA) break;
printf("もう一度生徒数を入力してください。");
}
for (i = 0; i < X; i++) {
printf("試験の成績を入力してください。\n");
printf("%d 人目:",i+1);
scanf("%d", &d[i]);
printf("この人の出席番号を入力してください。\n");
scanf("%d" ,&a[i]);
}
for (i = 0; i < X-1; i++) {
j = i;
for (k = i+1; k < X; k++) {
if (d[j] < d[k] || d[j] == d[k] && a[j] > a[k]) j = k;
}
tmp = d[j]; d[j] = d[i]; d[i] = tmp;
tmp = a[j]; a[j] = a[i]; a[i] = tmp;
}
printf("今回の試験順位(昇順)\n");
k = 1;
for (i = 0; i < X; i++) {
if (i > 0 && d[i] != d[i-1]) k = i + 1;
printf("%d位.出席番号:%d 点数:%d\n", k, a[i], d[i]);
}
return 0;
}
このプログラムの実行例をいくつか挙げてみてください。
Re: 順位について
Posted: 2017年7月25日(火) 13:16
by しき
かずまさん返信ありがとうございます。
おかげでソースコードが完成しました!
なるほど勘違いしていたようです・・。
以下がかずまさんのコードの実行例になります。
コード:
今回集計する人数を入力=5
試験の成績を入力してください。
1 人目:100
この人の出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:50
この人の出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:50
この人の出席番号を入力してください。
9
試験の成績を入力してください。
4 人目:50
この人の出席番号を入力してください。
6
試験の成績を入力してください。
5 人目:30
この人の出席番号を入力してください。
4
今回の試験順位(昇順)
1位.出席番号:1 点数:100
2位.出席番号:2 点数:50
2位.出席番号:6 点数:50
2位.出席番号:9 点数:50
5位.出席番号:4 点数:30
------------------------------------------
今回集計する人数を入力=5
試験の成績を入力してください。
1 人目:0
この人の出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:10
この人の出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:0
この人の出席番号を入力してください。
6
試験の成績を入力してください。
4 人目:0
この人の出席番号を入力してください。
3
試験の成績を入力してください。
5 人目:100
この人の出席番号を入力してください。
1
今回の試験順位(昇順)
1位.出席番号:1 点数:100
2位.出席番号:2 点数:10
3位.出席番号:1 点数:0
3位.出席番号:3 点数:0
3位.出席番号:6 点数:0
確かにこれでもできました。
参考にさせていただきます!