std::vectorをインデックスをそのままにラムダ式でsortする


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;
}

参考