Edited at

C++で構造体やクラスをソートする方法まとめ

More than 1 year has passed since last update.

C++でクラスや構造体の入ったvectorコンテナをソートする時、「何と何を比較してソートするのか?」を定義しないといけない。幾つか方法があったので自分なりにまとめてみる。


その1 演算子オーバーロード


ソースコード

#include <iostream>

#include <vector>
using std::cin;
using std::cout;
using std::endl;

struct Info
{
std::string name;
int age;

Info(std::string inputted_name, int inputted_age)
{
name = inputted_name;
age = inputted_age;
}
bool operator<(const Info &another) const
{
return age < another.age;//年齢を比較
};
//2つのconstを付けないとコンパイルエラーになるので注意!!
};

int main(void)
{
std::vector<Info> info;
info.push_back(Info("foo", 17));
info.push_back(Info("bar", 80));
info.push_back(Info("baz", 30));

std::sort(info.begin(), info.end());//ソート実行

for (auto itr : info)
{
cout << "age:" << itr.age << " name:" << itr.name << endl;
}

return 0;
}


出力

age:17 name:foo

age:30 name:baz
age:80 name:bar


解説

operator<を定義しておく方法。sortする時に(暗黙的に)呼ばれたstd::lessoperator<を利用して比較を実行する、と理解している。

operator>を定義しておけば降順ソート(std::greaterを使う方法)もできる。


その2 比較関数を定義する


ソースコード

struct Info

{
std::string name;
int age;

Info(std::string inputted_name, int inputted_age)
{
name = inputted_name;
age = inputted_age;
}
};

bool cmp(const Info &a, const Info &b)
{
return a.age < b.age;
}

int main(void)
{
std::vector<Info> info;
info.push_back(Info("foo", 17));
info.push_back(Info("bar", 80));
info.push_back(Info("baz", 30));

std::sort(info.begin(), info.end(),cmp);//比較関数cmpを使用してsort

for (auto itr : info)
{
cout << "age:" << itr.age << " name:" << itr.name << endl;
}

return 0;
}


出力

age:17 name:foo

age:30 name:baz
age:80 name:bar


解説

sortする時に利用する関数を自力で作っておく方法。

不等号の向きを逆にすれば降順ソートになる。


その3 ラムダ式を使う


ソースコード

struct Info

{
std::string name;
int age;

Info(std::string inputted_name, int inputted_age)
{
name = inputted_name;
age = inputted_age;
}
};

bool cmp(const Info &a, const Info &b)
{
return a.age < b.age;
}

int main(void)
{
std::vector<Info> info;
info.push_back(Info("foo", 17));
info.push_back(Info("bar", 80));
info.push_back(Info("baz", 30));

std::sort(info.begin(), info.end(), [](const Info &a, const Info &b) {
return a.age < b.age;
});//比較関数をラムダ式で作る

for (auto itr : info)
{
cout << "age:" << itr.age << " name:" << itr.name << endl;
}

return 0;
}


出力

age:17 name:foo

age:30 name:baz
age:80 name:bar


解説

比較関数をラムダ式としてsort()の所に記述しただけ。シンプルな関数なのでラムダ式で書いたほうが分かりやすいかも?


その他

std::priority_queue()等にも使える。ダイクストラ法を使うときなどに役に立つかもしれない。