こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ソート

typedef struct{
int num;
char name[20];
char type_of_class[8];
double average
} data;

data seiseki[100];

int main()
{
data[0].num = 1;
strcpy(data[0].name, "山田太郎");
strcpy(data[0].type_of_class, "A_class");
data[0].average = 66.2;

data[1].num = 2;
strcpy(data[1].name, "鈴木二郎");
strcpy(data[1].type_of_class, "B_class");
data[1].average = 43.1;


data[2].num = 3;
strcpy(data[2].name, "佐藤三郎");
strcpy(data[2].type_of_class, "A_class");
data[2].average = 39.1;

data[3].num = 4;
strcpy(data[3].name, "加藤四郎");
strcpy(data[3].type_of_class, "Bclass");
data[3].average = 93.6;

data[4].num = 5;
strcpy(data[4].name, "石田五郎");
strcpy(data[4].type_of_class, "B_class");
data[4].average = 57.9;

data[5].num = 6;
strcpy(data[5].name, "草田六郎");
strcpy(data[5].type_of_class, "A_class");
data[5].average = 6.2;

//ソート処理
}

このように各値が決まってる時
まず同じクラスのものをソートし
その中でaverage(平均点)の高い順に並べるソートを行いたいと思います。
最終的には
1,山田一郎,A,66.2
3,佐藤三郎,A,39,1
6,草田六郎,A,6.2
4,加藤四郎,B,93,6
5,石田五郎,B,57.9
2,鈴木二郎,B,43.1

のような感じになってると思います。ソートは行ごとです。
入れ替えの関数はint型のとdouble型のとchar型の3タイプ用意しています。

void intswap(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}

void double(double * p, double *q)
{
double temp;
temp = *p;
*p = *q;
*q = temp;
}

void wordswap(char p[], charq[])
{
char *temp = strdup(p);
strcpy(p, q);
strcpy(q, temp);
free(temp);
}

残りがわかりません。
教えて下さい。

投稿日時 - 2009-07-07 10:13:50

QNo.5105274

すぐに回答ほしいです

質問者が選んだベストアンサー

とりあえず、データを交換する関数は

void swap (data *from, data *to);

だけで良いです。
data temp = *from;
*to = *from;
*from = temp;

で丸ごと交換可能。

あと、大小判定の関数を作るのが良いでしょう。

bool isLarge(data a, data b) // a > b なら true;
{
if (strcmp(a.type_of_class, b.type_of_class) == 0)
{// 同じクラスなら
return (a.average > b.average); // 平均で大小判定
}
else if (strcmp(a.type_of_class, b.type_of_class) > 0)
{
return true;
}
else
{
return false;
}
}

これで、ソートのアルゴリズムを調べて

if (a[i] > a[j]) ... とかあるところを、 if (isLarge(seiseki[i], seiseki
[j])) に
swap(&a, &b) ... を、swap(&seiseki[i], &seiseki[j]);
とかに書き換えれば、それらしいものが出来るはずですが。

ソートのアルゴリズムは、「大小判定」して、順番が違っていたら「入れ替え
る」ですから。

投稿日時 - 2009-07-07 11:08:25

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

☆クラスと平均点を結合し、いっしょくたにソートしています。

#include <stdio.h>

#define Bias(c) (('Z'-c)*1000.0) // A から Z クラス限定、ソートキーの下駄

#define NIN 6

typedef struct{
 int num;
 char name[20];
 char type_of_class[8];
 double average;
}STUDENT;

STUDENT sgWork[ NIN ] = { // 構造体の初期化

 { 1, "山田太郎", "A_class", 66.2 },
 { 2, "鈴木二郎", "B_class", 43.1 },
 { 3, "佐藤三郎", "A_class", 39.1 },
 { 4, "加藤四郎", "B_class", 93.6 },
 { 5, "石田五郎", "B_class", 57.9 },
 { 6, "草田六郎", "A_class", 6.2 } // 六ちゃん、ガンバ
};
void Output( void )
{
 int i;

 for( i = 0; i < NIN; i++ ){

  printf( "%d,", sgWork[ i ].num );
  printf( "%s,", sgWork[ i ].name );
  printf( "%c,", sgWork[ i ].type_of_class[ 0 ] ); // 先頭文字のみ
  printf( "%5.1lf\n", sgWork[ i ].average );
 }
 printf( "\n" );
}
void SwapStruct( STUDENT *sBig, STUDENT *sSml )
{
 STUDENT sTemp;

 sTemp = *sBig;
 *sBig = *sSml;
 *sSml = sTemp;
}
void main( void )
{
 int i, j;
 double dMax, dNext;

 Output();

 for( i = 0; i < ( NIN - 1 ); i++ ){

  dMax = Bias( sgWork[ i ].type_of_class[ 0 ] ) + sgWork[ i ].average;

  for( j = ( i + 1 ); j < NIN; j++ ){

   dNext = Bias( sgWork[ j ].type_of_class[ 0 ] ) + sgWork[ j ].average;

   if( dNext < dMax ) continue;

   SwapStruct( &sgWork[ j ], &sgWork[ i ] );

   dMax = dNext;
  }
 }
 Output();
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

投稿日時 - 2009-07-07 12:02:30

ANo.3

入れ替える関数なんか作っても無意味で, 比較する関数を作ることが重要.
比較関数は #2 でもいいけど
int cmp(const void *a, const void *b)
{
const data *pa = a, *pb = b;
int diff = strcmp(pa->type_of_class, pb->type_of_class);
if (diff) {
return diff;
} else if (pa->average > pb->average) {
return 1;
} else if (pa->average < pb->average) {
return -1;
} else {
return 0;
}
}
とすれば qsort がつかえてお手軽 (ただし効率は無視).

投稿日時 - 2009-07-07 11:42:17

ANo.1

ミスでは?
seiseki[0]とかにしないとダメだとおもうよ
それか
data seiskeiを
seiseki data[100]にするか

投稿日時 - 2009-07-07 10:45:02

補足

また盛大にみすってます。
data[○].□ → seiseki[○].□です。

投稿日時 - 2009-07-07 10:46:08