質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • C

    3561questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

実行時間の新しい順に並べ替えるコードをスッキリできますか?

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 154

sanchu52

score 137

ラックナンバーリサーチの実行時間を新しい順に並べるコードを書いたのですが
もう少しカッコイイ、コードに書き直せますか。教えていただければありがたいです。
表示は正常に動きます。char dtfile[]="LACKNUM.DAT"からTIME_DATA lst[]にデータを
取り込むコードを示していただければ、いいのですが。

//jikan_sort4.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAXCNT 100
#define NDATA ((sizeof(lst))/(sizeof(TIME_DATA)))
//char dtfile[]="LACKNUM.DAT";

typedef struct        // 構造体の宣言
{
    int tm_year;       
    int tm_mon;        
    int tm_mday;        
    int tm_hour;         
    int tm_min;        
    int tm_sec; 
    double score;
}TIME_DATA;

int main()
{
    TIME_DATA lst[]=
        {{2017, 9,16, 8,18,23,10.6},
          {2015,12, 7,19,59, 8, 8.0},
         {2016, 1, 3, 1, 9,11, 7.5},
         {2016, 4, 5,19,16, 8, 9.0},
         {2015, 6, 4,19, 2,44, 7.5},   
         {2016, 8, 7,22,31,52, 9.3},
         {2014, 1, 4,23,43,50,10.2},
         {2016, 5,31,21, 9,53, 7.0},
         {2014, 2,12,28,31,49,13.0},
         {2016, 2,28, 2,27,20, 7.8},
         {2015, 5, 2,16,43,32, 6.3},
         {2017, 9,14,10,21,18, 6.0},
         {2017, 9,16, 8,18,9, 8.6}};

    int i;

    printf("NDATA:%d\n",NDATA);

    printf( "■並べ替え前\n" );
    for(i=0; i<NDATA; i++){
       printf("%4d年 %2d月 %2d日 %2d時 %2d分 %2d秒 \n所要時間(score):%.1f\n\n",              // 構造体配列への読み出し
       lst[i].tm_year,lst[i].tm_mon,lst[i].tm_mday,
       lst[i].tm_hour,lst[i].tm_min,lst[i].tm_sec,lst[i].score);
    }

    // 並べ替え
    for ( int i=0; i<NDATA; i++ ) {
            for ( int j=i+1; j<NDATA; j++ ){
                     if (lst[i].tm_year*100+lst[i].tm_mon == lst[j].tm_year*100+lst[j].tm_mon){
                            if(lst[i].tm_mday*100+lst[i].tm_hour == lst[j].tm_mday*100+lst[j].tm_hour){
                                    if(lst[i].tm_min == lst[j].tm_min){
                                             if (lst[i].tm_sec < lst[j].tm_sec){
                                                 TIME_DATA temp = lst[i];
                                                 lst[i] = lst[j];
                                                 lst[j] = temp;
                                             }
                                    }else{
                                             if(lst[i].tm_min < lst[j].tm_min){         
                                                 TIME_DATA temp = lst[i];
                                                 lst[i] = lst[j];
                                                 lst[j] = temp;
                                             }
                                    }
                            }else{
                                    if(lst[i].tm_mday*100+lst[i].tm_hour < lst[j].tm_mday*100+lst[j].tm_hour){
                                            TIME_DATA temp = lst[i];
                                                     lst[i] = lst[j];
                                                     lst[j] = temp;
                                    }
                            }
                    }else{
                         if (lst[i].tm_year*100+lst[i].tm_mon < lst[j].tm_year*100+lst[j].tm_mon){
                                    TIME_DATA temp = lst[i];
                                            lst[i] = lst[j];
                                             lst[j] = temp;
                         }
                    }
            }

    }

   // 並べ替え後表示
    printf( "■並べ替え後\n" );
    for(i=0; i<NDATA; i++){
        printf("%4d年 %2d月 %2d日 %2d時 %2d分 %2d秒 \n所要時間(score):%.1f\n\n",              // 構造体配列への読み出し
               lst[i].tm_year,lst[i].tm_mon,lst[i].tm_mday,
               lst[i].tm_hour,lst[i].tm_min,lst[i].tm_sec,lst[i].score);
    }
    return 0;
}

/*
C:\MinGW\users\chap09\kadai>gcc -I. -o jikan_sort4 jikan_sort4.c -Wall

C:\MinGW\users\chap09\kadai>jikan_sort4
NDATA:13
■並べ替え前
2017年  9月 16日  8時 18分 23秒
所要時間(score):10.6

2015年 12月  7日 19時 59分  8秒
所要時間(score):8.0

2016年  1月  3日  1時  9分 11秒
所要時間(score):7.5

2016年  4月  5日 19時 16分  8秒
所要時間(score):9.0

2015年  6月  4日 19時  2分 44秒
所要時間(score):7.5

2016年  8月  7日 22時 31分 52秒
所要時間(score):9.3

2014年  1月  4日 23時 43分 50秒
所要時間(score):10.2

2016年  5月 31日 21時  9分 53秒
所要時間(score):7.0

2014年  2月 12日 28時 31分 49秒
所要時間(score):13.0

2016年  2月 28日  2時 27分 20秒
所要時間(score):7.8

2015年  5月  2日 16時 43分 32秒
所要時間(score):6.3

2017年  9月 14日 10時 21分 18秒
所要時間(score):6.0

2017年  9月 16日  8時 18分  9秒
所要時間(score):8.6

■並べ替え後
2017年  9月 16日  8時 18分 23秒
所要時間(score):10.6

2017年  9月 16日  8時 18分  9秒
所要時間(score):8.6

2017年  9月 14日 10時 21分 18秒
所要時間(score):6.0

2016年  8月  7日 22時 31分 52秒
所要時間(score):9.3

2016年  5月 31日 21時  9分 53秒
所要時間(score):7.0

2016年  4月  5日 19時 16分  8秒
所要時間(score):9.0

2016年  2月 28日  2時 27分 20秒
所要時間(score):7.8

2016年  1月  3日  1時  9分 11秒
所要時間(score):7.5

2015年 12月  7日 19時 59分  8秒
所要時間(score):8.0

2015年  6月  4日 19時  2分 44秒
所要時間(score):7.5

2015年  5月  2日 16時 43分 32秒
所要時間(score):6.3

2014年  2月 12日 28時 31分 49秒
所要時間(score):13.0

2014年  1月  4日 23時 43分 50秒
所要時間(score):10.2


C:\MinGW\users\chap09\kadai>

*/
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

// こんな比較関数を用意しておいて 

int cmp(const void *a1, const void *b1)
{
    long asum, bsum;
    const TIME_DATA *a = (const TIME_DATA*)a1;
    const TIME_DATA *b = (const TIME_DATA*)b1;
    asum = a->tm_year * 10000000000L + a->tm_mon * 100000000L + a->tm_mday * 1000000L + 
            a->tm_hour * 10000L + a->tm_min * 100L + a->tm_sec;
    bsum = b->tm_year * 10000000000L + b->tm_mon * 100000000L + b->tm_mday * 1000000L + 
            b->tm_hour * 10000L + b->tm_min * 100L + b->tm_sec;
    if (asum > bsum) return -1;
    else if (asum < bsum) return 1;
    return 0;
}

//.....

   // 並べ替えはこの一行で
   qsort(lst, NDATA, sizeof (TIME_DATA), cmp);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

すっきりしているかは微妙ですが、次のような関数を作るとネストが減ります。

int compare(TIME_DATA *data1, TIME_DATA *data2) {
    const int DATUM1_IS_BIGGER  =  1;
    const int DATUM1_IS_SMALLER = -1;
    const int DATA_ARE_EQUAL    =  0;

    if(data1->tm_year > data2->tm_year) return DATUM1_IS_BIGGER;
    if(data1->tm_year < data2->tm_year) return DATUM1_IS_SMALLER;

    if(data1->tm_mon  > data2->tm_mon ) return DATUM1_IS_BIGGER;
    if(data1->tm_mon  < data2->tm_mon ) return DATUM1_IS_SMALLER;

    if(data1->tm_mday > data2->tm_mday) return DATUM1_IS_BIGGER;
    if(data1->tm_mday < data2->tm_mday) return DATUM1_IS_SMALLER;

    if(data1->tm_hour > data2->tm_hour) return DATUM1_IS_BIGGER;
    if(data1->tm_hour < data2->tm_hour) return DATUM1_IS_SMALLER;

    if(data1->tm_min  > data2->tm_min ) return DATUM1_IS_BIGGER;
    if(data1->tm_min  < data2->tm_min ) return DATUM1_IS_SMALLER;

    if(data1->tm_sec  > data2->tm_sec ) return DATUM1_IS_BIGGER;
    if(data1->tm_sec  < data2->tm_sec ) return DATUM1_IS_SMALLER;

    if(data1->tm_year > data2->tm_year) return DATUM1_IS_BIGGER;
    if(data1->tm_year < data2->tm_year) return DATUM1_IS_SMALLER;

    return DATA_ARE_EQUAL;
}

バイト列を比較する方法もあると思いますが、ちょっと不安なのでここでは避けました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/27 10:14

    LouiSさんいつも回答ありがとうございます。int compare(const void *p, const void *q)
    {
    TIME_DATA* data1=(*(TIME_DATA**)p);
    TIME_DATA* data2=(*(TIME_DATA**)q);に変更してやってみましたが、■並べ替え前まで出て、エラーが出て止まります。
    とりあえずdaisuke7さんから頂いたコードで、つぎにすすみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3561questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。