小学校や中学校の様に夏休みの宿題がないので自由に過ごせますね。
なので、自分で目標をたて着実に進めていかないとニコニコするだけで夏休みは終わります。
今日はSTLのlistのメンバ関数であるsort()について説明します。
STLコンテナはvector/list/deque/map/multimap/stack/queue/setなどがありますが、
listだけsort()を持っています。
他のコンテナは<algorithm>の中にある、sort()でソートできます。
値をpushするときに勝手にソートする奴もいます。(set,map)
今回はlistのsort()について解説していきますが、これらをマスターすると
mapやsetの様にpushしたときに自動ソートするコンテナのキーを自作クラスにすることができます。
[0回]
intの場合でsortを呼ぶ場合のプログラムです。
適当に読み流してください。
#include <list>
#include <stdio.h>
#include <time.h>
void main()
{
using namespace std; // この関数内だけで「std::」を省く命令
list<int> int_list;
list<int>::iterator int_it;
srand((unsigned int)time(0));
// ランダムな整数値の0~9を代入
for(int i=0 ; i<10 ; i++)
{
int_list.push_back(rand()%10);
}
int_list.sort(); // 昇順ソート 小→大になります
}
intの場合はsort()を呼ぶことができますが、自作のクラスだと、どうなるでしょう?
class MyVec3
{
public:
float x,y,z;
// コンストラクタ
MyVec3()
{
// コンストラクタで適当な値をセット
x=(float)(rand()%100)*0.1f;
y=(float)(rand()%100)*0.1f;
z=(float)(rand()%100)*0.1f;
}
};
void main()
{
list<MyVec3> vec_list;
list<MyVec3>::iterator vec_it;
for(int i=0 ; i<10 ; i++)
{
MyVec3 tmp; // tmp=Temporary=一時、仮の、はかない、まにあわせの
vec_list.push_back( tmp );
}
vec_list.sort(); // エラー!!
}
赤い文字のところでコンパイルエラーになります。
MyVec3をどうやってsortすればいいんだよというコンパイラの戸惑いからエラーがいっぱいでます。
sortの仕方を教えるには、「
<」演算子を定義することでsortすることができます!
ではMyVec3を改良します。
class MyVec3
{
~~省略~~
bool operator< (const MyVec3& _right) const
{
return (this->z) < (_right.z); // 昇順 小→大
}
};
色を変えた所が追加した文になります。
bool operator< を定義すればいいんです!
これでコンパイルが無事通り、MyVec3のZを元に小さい順にソートされます。
「<」を定義してやることでsetやmapのキーになることができます。
これで、めでたしめでたしではありません。
Yでもやりたい~ってなりますね。身長順とかね!
ではさらにMyVec3追加します。
class MyVec3
{
~~省略~~
bool operator< (const MyVec3& _right) const
{
return (this->z) < (_right.z); // 昇順 小→大
}
struct SortY{
bool operator()(const MyVec3& _left,const MyVec3& _right) const
{
return _left.y<_right.y;// 昇順 小→大
}
};
};
void main()
{
list<MyVec3> vec_list;
list<MyVec3>::iterator vec_it;
for(int i=0 ; i<10 ; i++)
{
MyVec3 tmp; // tmp=Temporary=一時、仮の、はかない、まにあわせの
vec_list.push_back( tmp );
}
vec_list.sort( MyVec3::SortY() );
}
これで無事Yによるソートも可能になりました。
struct SortYのような構造体をいっぱいつくることで好きなようにソートすることができます。
この構造体はグローバルにおいてもいいのですが、MyVec3だけでしか使わないのでクラス内で構造体を作成しています。
補足:
bool operator()(~~引数~~); のような関数のことを叙述関数(ジョジュツ)orプレディケートと言います。
このプレディケートは様々なものに使えますが長くなりそうなので、
http://www.geocities.jp/ky_webid/cpp/library/017.html
この辺をみたりしてください。
sort find_if などのSTL系の標準関数などで利用できます。
一応確認できるソースも用意しておきました。
ソース
長くなりましたが、ここまで読んでくれてありがとうございます。
記事について、もしミスや問題点などがあったら指摘してほしいです。
byリーダ和田
PR
COMMENT