アプリ版:「スタンプのみでお礼する」機能のリリースについて

今、こちらのサイトを使ってC言語の勉強をしています。
http://c-lang.sevendays-study.com/problemex3.html
このURLの先にある probex6-6(難易度:★★★) で詰まっています。
合計点の高い順に並べ替えをどのように書いたらいいかわかりません。

合計点を表示するところまでは、できました。
#include <stdio.h>

#define SIZE 5

typedef struct {
int id;
int kokugo;
int sugaku;
int rika;
int shakai;
int eigo;
}student_data;

void setData(student_data*, int, int, int, int, int, int);
void showData(student_data*);

typedef student_data student_type;
int sum(student_type*);

void main()
{
student_data data[SIZE];
int i;
int id[] = { 1001,1002,1003,1004,1005 };
int kokugo[] = { 82,92,43,72,99 };
int sugaku[] = { 43,83,32,73,72 };
int rika[] = { 53,88,53,71,82 };
int shakai[] = { 84,79,45,68,91 };
int eigo[] = { 45,99,66,59,94 };

for (i = 0; i < SIZE; i++) {
setData(&data[i], id[i], kokugo[i], sugaku[i], rika[i], shakai[i], eigo[i]);
}
printf("番号 国語 数学 理科 社会 英語 合計\n");
showData(data);
}

void setData(student_data* data, int id, int kokugo, int sugaku, int rika, int shakai, int eigo)
{
data->id = id;
data->kokugo = kokugo;
data->sugaku = sugaku;
data->rika = rika;
data->shakai = shakai;
data->eigo = eigo;
}

void showData(student_data*data)
{
int i;

for (i = 0; i < SIZE; i++) {
printf("%d %d %d %d %d %d ", data->id, data->kokugo, data->sugaku, data->rika, data->shakai, data->eigo);
sum(data);
printf("\n");
data++;
}
}

int sum(student_type* data) {
int goukei;

goukei = data->kokugo + data->sugaku + data->rika + data->shakai + data->eigo;
printf("%d", goukei);
return;
}

A 回答 (4件)

ソート版です。


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

#define SIZE 5

typedef struct {
int id;
int kokugo;
int sugaku;
int rika;
int shakai;
int eigo;
} student_data;


typedef student_data student_type;

typedef struct {
student_type st;
int goukei;
} student_data2;
typedef student_data2 student_type2;
void setData(student_data2 *, int, int, int, int, int, int);
void showData(student_data2 *);
int sum(student_type2 *);
int compare(const void *data1,const void *data2);


void main()
{
student_data2 data[SIZE];
int i;
int id[] = { 1001, 1002, 1003, 1004, 1005 };
int kokugo[] = { 82, 92, 43, 72, 99 };
int sugaku[] = { 43, 83, 32, 73, 72 };
int rika[] = { 53, 88, 53, 71, 82 };
int shakai[] = { 84, 79, 45, 68, 91 };
int eigo[] = { 45, 99, 66, 59, 94 };

for (i = 0; i < SIZE; i++) {
setData(&data[i], id[i], kokugo[i], sugaku[i], rika[i], shakai[i],
eigo[i]);
}
printf("番号 国語 数学 理科 社会 英語 合計\n");
showData(data);
qsort(data,SIZE,sizeof(student_data2),&compare);
printf("番号 国語 数学 理科 社会 英語 合計\n");
showData(data);
}

void setData(student_data2 * data, int id, int kokugo, int sugaku, int rika,
int shakai, int eigo)
{
data->st.id = id;
data->st.kokugo = kokugo;
data->st.sugaku = sugaku;
data->st.rika = rika;
data->st.shakai = shakai;
data->st.eigo = eigo;
data->goukei = sum(data);
}

void showData(student_data2 * data)
{
int i;

for (i = 0; i < SIZE; i++) {
printf("%d %d %d %d %d %d ", data->st.id, data->st.kokugo, data->st.sugaku,
data->st.rika, data->st.shakai, data->st.eigo);
printf("%d", data->goukei);

printf("\n");
data++;
}
}

int sum(student_type2 * data)
{
int goukei;

goukei =
data->st.kokugo + data->st.sugaku + data->st.rika + data->st.shakai +
data->st.eigo;
return goukei;
}

int compare(const void *data1,const void *data2)
{
int ret;
student_type2 *d1 = (student_type2*)data1;
student_type2 *d2 = (student_type2*)data2;
ret = d2->goukei - d1->goukei;
return ret;
}
    • good
    • 0
この回答へのお礼

ありがとうございます。
できました~!!
qsortを勉強しておらず、手順がどうなっているか考えるのに手こずりました。。。
ちなみに、ソートを使わずに並べ替えする方法はありますでしょうか。。。

お礼日時:2020/11/16 13:53

>ちなみに、ソートを使わずに並べ替えする方法はありますでしょうか。

。。
簡単に思いつくのは、一旦、student_data data[SIZE];
の内容を、別のワーク(同じ構成)に移しておいて、
別のワークの1番大きいのを、student_data data[SIZE]の先頭にコピー
次に、2番目に大きいのをstudent_data data[SIZE]の2番目にコピー
・・・以下同様
のような方法でしょうか。

2番目、3番目に大きいのを探すのは大変なので、
1番大きいのを探して、コピーが終わったのち、その人の合計を-1にしておけば、次回も1番大きいのを探すと、それは自動的に2番目に大きいものになります。
    • good
    • 0
この回答へのお礼

めんどうな感じになりそうですね…

同じ結果でも書き方が色々あって面白いです。
構造体とポインタでちょっと躓いています。
もっと勉強して、自分でポンポン答え出せるように頑張ります^^
ソース2つも書いていただきありがとうございました。

お礼日時:2020/11/16 14:20

student_dataを変えたくないということなのでラップして


student_data2を作りました。未ソートの状態です。これで同じ結果になります。尚、sumは印字をせず、合計を返すだけにしました。(これが本来のsumの姿です)次にソート版を投稿します。
-------------------------------------
#include <stdio.h>

#define SIZE 5

typedef struct {
int id;
int kokugo;
int sugaku;
int rika;
int shakai;
int eigo;
} student_data;


typedef student_data student_type;

typedef struct {
student_type st;
int goukei;
} student_data2;
typedef student_data2 student_type2;
void setData(student_data2 *, int, int, int, int, int, int);
void showData(student_data2 *);
int sum(student_type2 *);


void main()
{
student_data2 data[SIZE];
int i;
int id[] = { 1001, 1002, 1003, 1004, 1005 };
int kokugo[] = { 82, 92, 43, 72, 99 };
int sugaku[] = { 43, 83, 32, 73, 72 };
int rika[] = { 53, 88, 53, 71, 82 };
int shakai[] = { 84, 79, 45, 68, 91 };
int eigo[] = { 45, 99, 66, 59, 94 };

for (i = 0; i < SIZE; i++) {
setData(&data[i], id[i], kokugo[i], sugaku[i], rika[i], shakai[i],
eigo[i]);
}
printf("番号 国語 数学 理科 社会 英語 合計\n");
showData(data);

}

void setData(student_data2 * data, int id, int kokugo, int sugaku, int rika,
int shakai, int eigo)
{
data->st.id = id;
data->st.kokugo = kokugo;
data->st.sugaku = sugaku;
data->st.rika = rika;
data->st.shakai = shakai;
data->st.eigo = eigo;
data->goukei = sum(data);
}

void showData(student_data2 * data)
{
int i;

for (i = 0; i < SIZE; i++) {
printf("%d %d %d %d %d %d ", data->st.id, data->st.kokugo, data->st.sugaku,
data->st.rika, data->st.shakai, data->st.eigo);
printf("%d", data->goukei);

printf("\n");
data++;
}
}

int sum(student_type2 * data)
{
int goukei;

goukei =
data->st.kokugo + data->st.sugaku + data->st.rika + data->st.shakai +
data->st.eigo;
return goukei;
}
    • good
    • 0

1.構造体の中に合計を追加するのは反則ですか。


typedef struct {
int id;
int kokugo;
int sugaku;
int rika;
int shakai;
int eigo;
int goukei; //追加
}student_data;
のようにすることです。

2.qsortを使うのが最も簡単ですが、それを使うのは反則ですか。
    • good
    • 0
この回答へのお礼

コメントありがとうございます。

どちらも反則ではありませんが、
1に関して「この構造体を使って」というルールがあるため悩んでいます・・・。

お礼日時:2020/11/16 11:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A