qsortの利用

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

qsortの利用

#1

投稿記事 by Cひさしぶり » 11年前

qsortで二次元配列を成績1の順に整列し,表示したいものです。
以下はエラーのあるプログラムです。
Windows 8 gcc でコンパイルしました。

コード:

#include<stdio.h>
#include <stdlib.h>
double get_ave(int *);
void get_hyouka(double, char*);
void print_data(int, int* ,double,char);
int cmp( const void *p, const void *q ) {
    return *(int*)p - *(int*)q;
}
int main (void)
{
   int no[4],data[4][4];
   double ave[4];
    char hyouka[4];
   int i;
   printf("番号 成績1 成績2 成績3 成績4 入力:\n");
   for(i=0;i<4;i++){

   printf("%d人目\n",i+1);
   scanf("%d  %d  %d  %d  %d",&no[i],&data[i][0],&data[i][1],
          &data[i][2],&data[i][3]);
 
                    }
 printf("番号 成績1 成績2 成績3 成績4 平均 評価\n");
     for(i=0;i<4;i++){
         ave[i]=get_ave(data[i]);
         get_hyouka(ave[i],&hyouka[i]);
         print_data(no[i],data[i],ave[i],hyouka[i]); 

                       } 
qsort( data[1], 4, sizeof(int), cmp );
for(i=0;i<4;i++){
printf("%d  %d  %d  %d  %d\n",no[i],data[i][0],data[i][1],
          data[i][2],data[i][3]);;
}
 
 }

double get_ave(int *p_ten){
           int i;
          double ave=0.0;
        for(i=0;i<4;i++){
             ave+=*p_ten;
                         }
            ave/=4;
             return(ave);
                               }
void get_hyouka(double ave,char *p_hyouka){
   if(ave<60.0) *p_hyouka='D';
    else if(ave<70.0)*p_hyouka='C';
    else if(ave<80.0)*p_hyouka='B';
    else *p_hyouka='A';


                                          }

void print_data(int no,int *p_ten,double ave,char hyouka){
    int i;
    printf("%4d",no);
    for(i=0;i<4;i++){
     printf("  %6d",*p_ten++ );

                     }
      printf("%6.2f %c\n",ave,hyouka);

         }

何人めかの、得点の高い成績が後ろに表示されてしまいます。
整列前
番号 成績1 成績2 成績3 成績4
1 50 3012 62 33
整列後
1 33 50 62 3012
成績1の順に整列し,表示したいです。お返事お願いします。

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

Re: qsortの利用

#2

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

Cひさしぶり さんが書きました:qsortで二次元配列を成績1の順に整列し,表示したいものです。
「~したいものです。」という語尾が特徴的だと思ったのですが、まさかポップするさんと同一人物ではないですよね?
しかも、Windows8、gcc(mingw32)という環境もたまたま一致しているようですね。
スタックのデータ表示 • C言語交流フォーラム ~ mixC++ ~
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: qsortの利用

#3

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

インデントはポップするさん以上にデタラメのようですね。きちんとコードを整形するべきだと思います。

data[1]のみをソートするのではなく、data[0]、data[1]、data[2]、data[3]それぞれについてソートするべきではないでしょうか?
しかし、そもそもこれだと「成績1の順」ではない気がしますし…?
完全なサンプル入出力をいただけないでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: qsortの利用

#4

投稿記事 by softya(ソフト屋) » 11年前

ポップするさんと同一人物のようです。
と言うことで名前の統一をお願いします。
http://dixq.net/board/board.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かずま

Re: qsortの利用

#5

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

return *(int *) p - *(int *) q; を
return (*(int (*)[4])p)[0] - (*(int (*)[4])q)[0]; に変更し、
qsort(data[1], 4, sizeof(int), cmp); を
qsort(data, 4, sizeof(int[4]), cmp); に変更すると、
二次元配列 data 全体を成績1 により昇順にソートできますが、
配列 no はソートされません。それでいいのでしょうか?

インデントって何かわかりますか?

コード:

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

double get_ave(int *);
void get_hyouka(double, char *);
void print_data(int, int *, double, char);

int cmp(const void *p, const void *q)
{
    return (*(int (*)[4])p)[0] - (*(int (*)[4])q)[0];
}

int main(void)
{
    int no[4], data[4][4];
    double ave[4];
    char hyouka[4];
    int i;
    printf("番号 成績1 成績2 成績3 成績4 入力:\n");
    for (i = 0; i < 4; i++) {
        printf("%d人目\n", i + 1);
        scanf("%d  %d  %d  %d  %d",
            &no[i], &data[i][0], &data[i][1], &data[i][2], &data[i][3]);
    }
    printf("番号 成績1 成績2 成績3 成績4 平均 評価\n");
    for (i = 0; i < 4; i++) {
        ave[i] = get_ave(data[i]);
        get_hyouka(ave[i], &hyouka[i]);
        print_data(no[i], data[i], ave[i], hyouka[i]);
    }
    qsort(data, 4, sizeof(int[4]), cmp);
    for (i = 0; i < 4; i++) {
        printf("%d  %d  %d  %d  %d\n",
            no[i], data[i][0], data[i][1], data[i][2], data[i][3]);;
    }
}

double get_ave(int *p_ten)
{
    int i;
    double ave = 0.0;
    for (i = 0; i < 4; i++) {
        ave += *p_ten;
    }
    ave /= 4;
    return (ave);
}

void get_hyouka(double ave, char *p_hyouka)
{
    if (ave < 60.0)
        *p_hyouka = 'D';
    else if (ave < 70.0)
        *p_hyouka = 'C';
    else if (ave < 80.0)
        *p_hyouka = 'B';
    else
        *p_hyouka = 'A';
}

void print_data(int no, int *p_ten, double ave, char hyouka)
{
    int i;
    printf("%4d", no);
    for (i = 0; i < 4; i++) {
        printf("  %6d", *p_ten++);
    }
    printf("%6.2f %c\n", ave, hyouka);
}

かずま

Re: qsortの利用

#6

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

ave += *p_ten; となっていますが、
これは、ave += p_ten; 、
または ave += *p_ten++; の間違いでしょう。

Cひさしぶり

Re: qsortの利用

#7

投稿記事 by Cひさしぶり » 11年前

Nameを統一せず、しつれいしました。

かずま

Re: qsortの利用

#8

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

Cひさしぶり さんが書きました: 何人めかの、得点の高い成績が後ろに表示されてしまいます。
整列前
番号 成績1 成績2 成績3 成績4
1 50 3012 62 33
整列後
1 33 50 62 3012
「何人めかの」って言っていますが、
番号が 1 だから 一人目ですよね。

「得点の高い成績が後ろに表示されてしまいます。」
comp で p と q の差を返していますから、
qsort が昇順にソートするのは当然です。
高い成績を前のほうにしたければ、p と q を入れ替えましょう。

qsort( data[1], 4, sizeof(int), cmp );
これだと、二人目の 4つの成績(int) をソートしますね。
data[0] にしないと一人目のソートはしないはずですが。
Cひさしぶり さんが書きました:成績1の順に整列し,表示したいです。お返事お願いします。
意味不明です。
次の入力に対して、どんな出力を期待していますか?

コード:

1 65 95 90 60
2 65 60 70 70
3 90 80 65 65
4 45 55 45 95

Cひさしぶり

Re: qsortの利用

#9

投稿記事 by Cひさしぶり » 11年前

4 45 55 45 95
1 65 95 90 60
2 65 60 70 70
3 90 80 65 65
としたいです。掲示板のマナーがまもれずすいませんでした。

Bull
記事: 149
登録日時: 11年前

Re: qsortの利用

#10

投稿記事 by Bull » 11年前

Cひさしぶり さんが書きました:4 45 55 45 95
1 65 95 90 60
2 65 60 70 70
3 90 80 65 65
としたいです。
こうゆうことでしょうか

コード:

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

int cmp(const void *p, const void *q)
{
	return ((int *)p)[1] - ((int *)q)[1];
}

int main(void)
{
	int		i;

	int		data[][5] = {
		{ 1, 65, 95, 90, 60, },
		{ 2, 65, 60, 70, 70, },
		{ 3, 90, 80, 65, 65, },
		{ 4, 45, 55, 45, 95, },
	};

	qsort(data, sizeof data / sizeof *data, sizeof *data, cmp);

	for (i = 0; i < sizeof data / sizeof *data; ++i)
		printf("%2d: %2d %2d %2d %2d\n", data[i][0], data[i][1], data[i][2], data[i][3], data[i][4]);

	return 0;
}
ただし、qsort() は安定なソートではありませんので、2番目と3番目の順番は不定です。

Cひさしぶり

Re: qsortの利用

#11

投稿記事 by Cひさしぶり » 11年前

ソースコードありがとうございます。参考にします。

閉鎖

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