C++で構造体やクラスをソートする方法まとめ
(Qiitaを退会したため,同名の記事をQiitaからはてなにコピーしました)
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::less
がoperator<
を利用して比較を実行する、と理解している。
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()
等にも使える。ダイクストラ法を使うときなどに役に立つかもしれない。