std::vector
をインデックスそのままでソートしたいな,でもコード内でそんなにたくさん使うわけじゃないしわざわざ比較関数定義したくないなみたいなときに以下のやり方が便利かもしれない
#include <iostream>
#include <vector>
#include <algorithm>
int main(int argc, char **argv){
//適当にvectorをつくる
std::vector<int> vec;
vec.push_back(3);
vec.push_back(7);
vec.push_back(1);
vec.push_back(2);
vec.push_back(9);
vec.push_back(4);
vec.push_back(6);
//pairの入ったvectorの定義
typedef std::pair<int, int> pair;
std::vector<pair> pair_vec;
//pair入りvectorに添字とvectorの中身を挿入
std::cout << "before sort" << std::endl;
for(int i=0; i<vec.size(); i++){
pair_vec.push_back(pair(i, vec[i]));
std::cout << i << " " << vec[i] << std::endl;
}
//ラムダ式で比較式を書く
std::sort(
pair_vec.begin(),
pair_vec.end(),
[](const pair& x, const pair& y){return x.second < y.second;}
);
std::cout << "after sort" << std::endl;
for(auto& i: pair_vec){
std::cout << i.first << " " << i.second << std::endl;
}
return 0;
}
実行結果
before sort
0 3
1 7
2 1
3 2
4 9
5 4
6 6
after sort
2 1
3 2
0 3
5 4
6 6
1 7
4 9
追記(2017/8/24)
@yumetodo 氏にstd::iota
を使えばよいのではと意見をいただいたいので,参考に書いてみました.圧倒的にシンプルでいいですね….
#include <iostream>
#include <vector>
#include <algorithm>
int main(int argc, char **argv){
//適当にvectorをつくる
std::vector<int> vec;
vec.push_back(3);
vec.push_back(7);
vec.push_back(1);
vec.push_back(2);
vec.push_back(9);
vec.push_back(4);
vec.push_back(6);
std::vector<int> index(vec.size());
std::iota(index.begin(), index.end(), 0);
std::cout << "before sort" << std::endl;
for(auto& i:index){
std::cout << i << " " << vec[i] << std::endl;
}
std::sort(
index.begin(),
index.end(),
[&](int x, int y){return vec[x] < vec[y];}
);
std::cout << "after sort" << std::endl;
for(auto& i:index){
std::cout << i << " " << vec[i] << std::endl;
}
return 0;
}
参考
- vectorの配列番号をメモったまま(部分的に)並び変える
- vectorをインデックスと一緒にpairに突っ込むのはここを参考にしました
- C++11のラムダ関数の簡単なまとめ
- ラムダ式を使ったソートはここを参考にしました