自作オブジェクトのソート

container-sort.png

はいっ にゃんこクラスの人〜 背の順に並んで〜!


ソートをしなくても必ず必要なメンバ
コンテナに自作クラスを入れるには、以下の3つを必ず書かなくてはならない

  • デフォルトコンストラクタ
  • コピーコンストラクタ
  • デストラクタ
// コピーコンストラクタは、メンバー変数のコピーなので必要ないが一応作っておく
    // [const]を忘れると、エラーになる
    TestClass(const TestClass &source){
        m_n  = source.m_n;
        m_ch = source.m_ch;
    }

更に、ソート機能を使うなら必要なメンバ
    // 比較演算子(findで必要)
    // [const]を忘れるとエラー
    bool operator==(const TestClass &a)const{
        return m_n == a.m_n && m_ch == a.m_ch ;
    }
 
    // 比較演算子(sortで必要)
    // [const]を忘れるとエラー
    bool operator<(const TestClass &a)const{
        return m_n < a.m_n;//小さいのから大きい順番に並べたいとき
    }

もっと楽な書き方
オブジェクトの継承関係が複雑な場合は比較関数を定義する方法の方が楽かもしれない
typedef struct MyStruct
{    
    float distance;
    float index;
    //ソートする時に使う比較関数
    static bool compare(const MyStruct& firstElem, const MyStruct& secondElem) {
        return firstElem.distance < secondElem.distance;
    }
} MyStruct;

比較関数を構造体のstatic関数として定義しておくと、整理しやすい。

実際にソートする時

std::vector<MyStruct> array(10);
std::sort(std::begin(array), std::end(array), MyStruct::compare);

自作クラスを入れたコンテナでソートしてみよう★

import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        Voxel[] mVoxels=new Voxel[5];
        for(int i=0;i<5;i++){mVoxels[i]=new Voxel();mVoxels[i].index=i;}
        mVoxels[0].mEyeDis=0.1f;
        mVoxels[1].mEyeDis=0.0f;
        mVoxels[2].mEyeDis=0.3f;
        mVoxels[3].mEyeDis=0.5f;
        mVoxels[4].mEyeDis=0.01f;
        Arrays.sort(mVoxels);
        for(int i=0;i<5;i++){System.out.println("["+mVoxels[i].index+"]"+mVoxels[i].mEyeDis);}
    }
}

別のやり方

public class MyComparator implements Comparator {  
    public int compare(Object arg0, Object arg1) {  
        return 1;   //0:等しい。1:より大きい。-1:より小さい  
    }

実際にソートする時

vector<MyObject> mylist;
sort(mylist.begin(),mylist.end());

本当に自作オブジェクトが必要??無名関数で代用できないか考えよう。

何かの目的があって、ソートのために自作オブジェクトを作るとする。
その自作オブジェクトのメンバが2個だけとかだったら、無名関数で代用できる可能性が高い。

int p=8;//たとえば、ある値pとの差が最も小さいものを探したい場合。
auto nearest = min_element(v.begin(),v.end(),[&](const int& a,const int& b){return abs(a-p)<abs(b-p);});

無名関数はtrue or falseを返すものにする

array cplus java myclass set sort static template-method

サポートサイト Wikidot.com arraycplusjavamyclasssetsortstatictemplate-method