出席番号について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
しき

出席番号について

#1

投稿記事 by しき » 2年前

先ほど「選択ソートについて質問です」を投稿したものです。
「学生の出席番号と試験の成績が入力として与えられるときに試験の成績 の順に成績と出席番号を出力するプログラムを作成せよ」という問題の続きなのですが、出席番号をうまく出力できていません。
実行結果は下に記した通りで、一番最後に入力した数値(出席番号)しか出力されません。どうすれば解決するのでしょうか。よろしくお願いします。
ーーーーーーーーーーーーーー                 
今回集計する人数を入力=2
試験の成績を入力してください。
1 人目:80
次に出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:90
次に出席番号を入力してください。
2
今回の試験順位(昇順)
点数:90
出席番号:2
点数:80
出席番号:2
ーーーーーーーーーーーーーー

コード:

#include <stdio.h>
#define MAXDATA 100
int main()
{
  int d[MAXDATA];
  int X;
  int a;
  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);
  }
  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;
  }
  for (i = 0; i < X; i++) {
    printf("点数:%d\n", d[i]);
    printf("出席番号:%d\n", a);
}
}

アバター
みけCAT
記事: 6149
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: 出席番号について

#2

投稿記事 by みけCAT » 2年前

1人分の出席番号しか保存していないので、1人分しか出力されないのは当たり前ですね。
試験の成績と同様に、人数分(以上)の配列を確保し、そこに保存すればいいでしょう。
試験の成績と出席番号をまとめた構造体を作って管理するのもいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

しき

Re: 出席番号について

#3

投稿記事 by しき » 2年前

みけCATさん。返信ありがとうございます。
無事解決しました!

アバター
asd
記事: 302
登録日時: 8年前

Re: 出席番号について

#4

投稿記事 by asd » 2年前

しき さんが書きました:みけCATさん。返信ありがとうございます。
無事解決しました!
最終的なソースを提示しておくと、本当に解決しているのか、他の問題点がないかをほかの方が確認できるかもしれませんね。
Advanced Supporting Developer
無理やりこじつけ(ぉ

しき

Re: 出席番号について

#5

投稿記事 by しき » 2年前

asdさんありがとうございます。

最終コードは以下の通りです

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int X;
  int a[ATTEND];
  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;
  }
  for (i = 0; i < X; i++) {
 printf("出席番号:%d  ", a[i]); printf("点数:%d\n", d[i]);

  }

}

かずま

Re: 出席番号について

#6

投稿記事 by かずま » 2年前

実行結果

コード:

今回集計する人数を入力=3
試験の成績を入力してください。
1 人目:80
次に出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:90
次に出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:70
次に出席番号を入力してください。
3
今回の試験順位(昇順)
出席番号:1  点数:90
出席番号:2  点数:80
出席番号:3  点数:70
点数が 90 の人の出席番号は 2 なんですが、1 になっていますよ。
これでいいんですか?

しき

Re: 出席番号について

#7

投稿記事 by しき » 2年前

かずまさん確認ありがとうございます。
確認したところこれでは確かにこれではだめでした。
もう一度作り直してみようと思います。

しき

Re: 出席番号について

#8

投稿記事 by しき » 2年前

文字を一つ足してそれをそのままというわけにはいかないんですね・・。
これだと  Segmentation fault (コアダンプ)  というのがでてうまくいきません。
解決策を教えてください。

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int X;
  int a[ATTEND];
  int i, j, k,l;
  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[l]);
 
 }
  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;
  }
  for (i = 0; i < X; i++) {
 printf("出席番号:%d  ", a[l]); printf("点数:%d\n", d[i]);
 
  }
 
}

アバター
asd
記事: 302
登録日時: 8年前

Re: 出席番号について

#9

投稿記事 by asd » 2年前

しき さんが書きました:文字を一つ足してそれをそのままというわけにはいかないんですね・・。
これだと  Segmentation fault (コアダンプ)  というのがでてうまくいきません。
解決策を教えてください。
lという変数は宣言されているだけで値が設定されていないので、0以外の変な値が入っているかもしれません。
その結果a[l]という指定はlの値によっては配列の範囲外になってしまうかもしれませんね。
それでSegmentation faultが起きているのではと思います。

最終形として提示していただいたソースで足りなかったのは、
点数が格納されているdはソートしているけど、それとセットになっているはずの出席番号が入っているaはノータッチだったことにあります。

であれば、dをソートして入れ替えているところで、同じようにaも入れ替えてしまえばどうでしょうか?
しき さんが書きました:

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int X;
  int a[ATTEND];
  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;
      //出席番号が入っているaも点数のdと同じように入れ替える必要がある
  }
  for (i = 0; i < X; i++) {
      printf("出席番号:%d  ", a[i]); printf("点数:%d\n", d[i]);
  }
 
}
上記のコメント箇所で出席番号も入れ替えて点数の配列dとセットでソートされるようにしてみてください。
Advanced Supporting Developer
無理やりこじつけ(ぉ

しき

Re: 出席番号について

#10

投稿記事 by しき » 2年前

asdさん返信ありがとうございます。
なんとかできました!

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int X;
  int a[ATTEND];
  int i, j, k,l;
  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[l]);
 
 }
  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;
  j=i;
      for(k=i+1; k < X; k++){
        if(d[j]<d[k]){ j = k; }
      }
      tmp = a[j];
      a[j] = a[i];
      a[i] = tmp;

      //変更しました
}
  for (i = 0; i < X; i++) {
 printf("出席番号:%d  ", a[l]); printf("点数:%d\n", d[i]);
 
  }
 
}

しき

Re: 出席番号について

#11

投稿記事 by しき » 2年前

誤ったものを送ってしまいました。

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int a[ATTEND];
  int X;
  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;

      j=i;
 for(k=i+1; k < X; k++){
        if(d[j]<d[k]){ j = k; }
      }
      tmp = a[j];
      a[j] = a[i];
      a[i] = tmp;
  }

  for (i = 0; i < X; i++) {
    printf("出席番号:%d  ", a[i]); printf("点数:%d\n", d[i]);

  }

}

しき

Re: 出席番号について

#12

投稿記事 by しき » 2年前

連投ですみません
ーーーーーーーーーーーーー
今回集計する人数を入力=3
試験の成績を入力してください。
1 人目:90
次に出席番号を入力してください。
8
試験の成績を入力してください。
2 人目:60
次に出席番号を入力してください。
9
試験の成績を入力してください。
3 人目:20
次に出席番号を入力してください。
1
今回の試験順位(昇順)
出席番号:8 点数:90
出席番号:9 点数:60
出席番号:1 点数:20
ーーーーーーーーーーーー
今回集計する人数を入力=3
試験の成績を入力してください。
1 人目:80
次に出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:90
次に出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:70
次に出席番号を入力してください。
3
今回の試験順位(昇順)
出席番号:1 点数:90
出席番号:2 点数:80
出席番号:3 点数:70
ーーーーーーーーーーーーーー

やはりうまくいきませんでした・・。

アバター
asd
記事: 302
登録日時: 8年前

Re: 出席番号について

#13

投稿記事 by asd » 2年前

しき さんが書きました: やはりうまくいきませんでした・・。
はい、提示いただいた修正後のソースでは「ソート後の成績配列を再度調べてソート」しようとしています。
ソート後の配列を調べてももうソートしようがないので出席番号はソートされないわけですね。

コメントを付与しますのでどこでソート(成績の入れ替え方の判定)を行っているかを確認してみてください。
もう一歩だと思うので頑張ってください。
しき さんが書きました:

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int a[ATTEND];
  int X;
  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; }
      }
      //ここでソート前の成績に基づいて入れ替えを行っている(j番目とi番目の入れ替え)
      tmp = d[j];
      d[j] = d[i];
      d[i] = tmp;
      //成績と同じように出席番号もj番目とi番目を入れ替えないと成績と出席番号の対応関係が壊れてしまう

      //既にj番目とi番目を入れ替えることは上で分かっているので再度調べなくても…
      j=i;
      for(k=i+1; k < X; k++){
        if(d[j]<d[k]){ j = k; }
      }

      tmp = a[j];
      a[j] = a[i];
      a[i] = tmp;
  }

  for (i = 0; i < X; i++) {
    printf("出席番号:%d  ", a[i]); printf("点数:%d\n", d[i]);

  }

}
Advanced Supporting Developer
無理やりこじつけ(ぉ

しき

Re: 出席番号について

#14

投稿記事 by しき » 2年前

とっぱらったらできました!
今度こそ大丈夫だと思いますがどうでしょうか。
----------------------------------------
今回集計する人数を入力=3
試験の成績を入力してください。
1 人目:80
次に出席番号を入力してください。
1
試験の成績を入力してください。
2 人目:90
次に出席番号を入力してください。
2
試験の成績を入力してください。
3 人目:70
次に出席番号を入力してください。
3
今回の試験順位(昇順)
出席番号:2 点数:90
出席番号:1 点数:80
出席番号:3 点数:70
----------------------------------

コード:

#include <stdio.h>
#define MAXDATA 100
#define ATTEND 30
int main()
{
  int d[MAXDATA];
  int a[ATTEND];
  int X;
  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; }
      }
      //ここでソート前の成績に基づいて入れ替えを行っている(j番目とi番目の入れ替え)
      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  ", a[i]); printf("点数:%d\n", d[i]);
 
  }
 
}


アバター
asd
記事: 302
登録日時: 8年前

Re: 出席番号について

#15

投稿記事 by asd » 2年前

しき さんが書きました:とっぱらったらできました!
今度こそ大丈夫だと思いますがどうでしょうか。
動作としてはよさそうですね。おめでとうございます(*´ヮ`)
最終ソースを載せてよかったですね。載せずにいたら出席番号がソートされていないことに気が付かないままだったかもしれませんし…。

若干気になるところとして、成績は100人分(MAXDATA)保持できるのに、出席番号は30人分(ATTEND)しか保持できないので、
どちらかに合わせてもよいのかなと思いました。

また、現状では集計人数に想定以上の人数を与えられてもそのまま成績と出席番号の格納処理へ進んでしまい、
用意している配列の上限を超えてしまう場合があるので、安全策として上限以上の人数を入れられたら
人数の入力をやり直してもらうなり、配列の要素数の上限に丸めるなりしておくとよいかもです。

さらに、現在は成績と出席番号が別々の配列になっているため同期をとって入れ替える必要がありますが、
構造体を習うとこれら複数の要素をまとめて一つの要素として扱えるのでそちらも余力があれば構造体対応版に改良してみてもよいかもですね。
Advanced Supporting Developer
無理やりこじつけ(ぉ

しき

Re: 出席番号について

#16

投稿記事 by しき » 2年前

今までアドバイスありがとうございました!
保持のところは合わせて、MAXDATA以上入れたらやり直しさせるように改良しました。
構造対応版の方は構造体を習ってからにしようと思います。

コード:

#include <stdio.h>
#define MAXDATA 100
int main()
{
  int d[MAXDATA];
  int a[MAXDATA];
  int X;
  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; }
      }
      //ここでソート前の成績に基づいて入れ替えを行っている(j番目とi番目の入れ替え)
      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  ", a[i]); printf("点数:%d\n", d[i]);
 
  }
 
}

返信

“C言語何でも質問掲示板” へ戻る