叙述関数とは
ソートなどの判定基準となる関数
である

STLを使うとDebugモードが重いので
STLのsortを使わずに
qsort関数を使ったクイックソートをしてみる
まぁ、ゲッター(GetDate、GetNum)だけconstメンバ関数にすることに気をつければクラスでもできた

標準のクイックソート関数qsortを使う場合でも
この関数を記述する必要がある

まぁ、ゲッター(GetDate、GetNum)だけconstメンバ関数にすることに気をつければクラスでもできる
注意としてはconstメンバ関数内で呼び出せるのは同様のconstメンバ関数と書き換えをしないメンバ変数のみ
要するにconstメンバ関数内では書き換えされない保証があるものしか呼べない
これを忘れるとエラーでまくりで結構はまる

     //qsort関数を使ったソート
    #define _CRT_SECURE_NO_DEPRECATE
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define DATASIZE 6
    
    // データクラス
    class DateNum
    {
    private:
        char date[1024];
        int num;
    public:
        
        void Set(char *date,int num)
        {
            strcpy(this->date,date);
            this->num = num;
        }
    
        const char* GetDate() const{return date;} // constメンバ関数にする
        const int GetNum() const{return num;} // constメンバ関数にする
    
        DateNum(){}
        virtual ~DateNum(){}
    };
    
    // 叙述関数(比較方法)
    //*a が *b よりも先であるとき 負の値
    //*a と *b とのどちらが先でもいいとき  0
    //*a が *b よりも後であるとき 正の値
    int compare(const void *a, const void *b)
    {
        //引数に const ポインタを使うと、そのポインタから
        //非 const メンバ関数は呼び出せない
    
        DateNum *p,*q;
        p = (DateNum *)a;
        q = (DateNum *)b;
    
        // 日時が全く同じだった場合
        if(strcmp(p->GetDate(),q->GetDate()) == 0)
        {
            // 番号で順序もソート
            return p->GetNum() - q->GetNum(); // b->num,a->numなら降順
        }
        else
            return strcmp(p->GetDate(),q->GetDate()); // b->date,a->dateなら降順
    }
    
    int main()
    {
        DateNum datenum[DATASIZE];
        char *date[DATASIZE] = {"2009/10/01 09:00:04","2009/10/01 10:00:01","2009/10/01 12:00:00","2009/10/01 11:00:10","2009/10/01 12:00:00","2009/10/01 12:00:00"};
        int num[DATASIZE] = {6,3,1,5,4,2};
        int i;
    
        for(i = 0;i < DATASIZE;++i)
            datenum[i].Set(date[i],num[i]);
    
    
        // ソート前表示
        for (i = 0; i < DATASIZE; i++) {
            printf("%s ", datenum[i].GetDate());
            printf("%d \n", datenum[i].GetNum());
        }
        printf("\n");
    
    
        // ソートしたいデータ、ソートしたいデータの要素数、1つの要素のサイズ、叙述関数への関数ポインタ
        qsort(datenum, DATASIZE, sizeof(DateNum), compare);
    
        // ソート結果表示
        for (i = 0; i < DATASIZE; i++) {
            printf("%s ", datenum[i].GetDate());
            printf("%d \n", datenum[i].GetNum());
        }
        printf("\n");
    }

使い方はSTLの叙述関数(ソートの判定関数)と似てる
マージソートが標準関数にないところが残念なところ

 //qsort関数を使ったソート
 
 #define _CRT_SECURE_NO_DEPRECATE
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #define DATASIZE 6
 
 // データクラス
 class DateNum
 {
 private:
 char date[1024];
 int num;
 public:
 
 void Set(char *date,int num)
 {
 strcpy(this->date,date);
 this->num = num;
 }
 
 const char* GetDate() const{return date;} // constメンバ関数にする
 const int GetNum() const{return num;} // constメンバ関数にする
 
 DateNum(){}
 virtual ~DateNum(){}
 };
 
 
 // 叙述関数(比較方法)
 //*a が *b よりも先であるとき 負の値
 //*a と *b とのどちらが先でもいいとき  0
 //*a が *b よりも後であるとき 正の値
 int compare(const void *a, const void *b)
 {
 //引数に const ポインタを使うと、そのポインタから
 //非 const メンバ関数は呼び出せない
 
 DateNum *p,*q;
 p = (DateNum *)a;
 q = (DateNum *)b;
 
 // 日時が全く同じだった場合
 if(strcmp(p->GetDate(),q->GetDate()) == 0)
 {
 // 番号で順序もソート
 return p->GetNum() - q->GetNum(); // b->num,a->numなら降順
 }
 else
 return strcmp(p->GetDate(),q->GetDate()); // b->date,a->dateなら降順
 }
 
 int main()
 {
 DateNum datenum[DATASIZE];
 char *date[DATASIZE] = {"2009/10/01 09:00:04","2009/10/01 10:00:01","2009/10/01 12:00:00","2009/10/01 11:00:10","2009/10/01 12:00:00","2009/10/01 12:00:00"};
 int num[DATASIZE] = {6,3,1,5,4,2};
 int i;
 
 for(i = 0;i < DATASIZE;++i)
 datenum[i].Set(date[i],num[i]);
 
 
 // ソート前表示
 for (i = 0; i < DATASIZE; i++) {
 printf("%s ", datenum[i].GetDate());
 printf("%d \n", datenum[i].GetNum());
 }
 printf("\n");
 
 
 // ソートしたいデータ、ソートしたいデータの要素数、1つの要素のサイズ、叙述関数への関数ポインタ
 qsort(datenum, DATASIZE, sizeof(DateNum), compare);
 
 // ソート結果表示
 for (i = 0; i < DATASIZE; i++) {
 printf("%s ", datenum[i].GetDate());
 printf("%d \n", datenum[i].GetNum());
 }
 printf("\n");
 }

#vote((^ω^)ktkr[0],普通[0],。(`ω´#)。なんじゃこりゃああ[0])


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS