c++ sort keeping track of indices
Adding to @Konrad answer:
If for some reason you are not able to use C++11, then you can use boost::phoenix
to simulate it like
#include <vector>
#include <algorithm>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
template <typename T>
std::vector<size_t> ordered(std::vector<T> const& values)
{
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
std::vector<size_t> indices(values.size());
int i = 0;
std::transform(values.begin(), values.end(), indices.begin(), ref(i)++);
std::sort(indices.begin(), indices.end(), ref(values)[arg1] < ref(values)[arg2]);
return indices;
}
You could try something like this:
template<typename C>
class index_sorter {
public:
compare(C const& c) : c(c) {}
bool operator()(std::size_t const& lhs, std::size_t const& rhs) const {
return c[lhs] < c[rhs];
}
private:
C const& c;
};
std::sort(index_vector.begin(), index_vector.end(), index_sorter(vector));
Using C++11, the following should work just fine:
template <typename T>
std::vector<size_t> ordered(std::vector<T> const& values) {
std::vector<size_t> indices(values.size());
std::iota(begin(indices), end(indices), static_cast<size_t>(0));
std::sort(
begin(indices), end(indices),
[&](size_t a, size_t b) { return values[a] < values[b]; }
);
return indices;
}