Sort one vector using another in non-increasing order

This means that when I sort v2 in non-increasing order, v1 should look like this:

The vectors are as follows.

v1 = {0, 5, 5, 2, 10}; v2 = {0 ,2, 6, 20, 5}; 

Exit:

 v1 = {2, 5, 10, 5, 0}; v2 = {20, 6, 5, 2, 0}; 

I tried to solve this problem of mixing std::sort and lambdas. This is why I read a few questions about std::sort , there were no answers that solve a problem similar to mine, so I ask.

I am particularly interested in answers containing its use or other features of C ++ 11 and C ++ 14.

It's not a question:

"I totally don't know what to do."

I know how to achieve results using C ++ 98, but I am wondering if there is a more efficient and beautiful way to do this.

Many thanks for the help:)

+6
source share
3 answers

You can zip , sort and unzip .

 #include <iostream> #include <vector> #include <algorithm> //converts two vectors into vector of pairs template <typename T, typename U> auto zip(T t, U u) { std::vector<std::pair<typename T::value_type,typename U::value_type>> pairs; for (size_t i = 0; i < t.size(); ++i){ pairs.emplace_back(u[i],t[i]); } return pairs; } //converts a vector of pairs, back into two two vectors template <typename T, typename U, typename V> void unzip(V pairs, T & t, U & u) { for (auto const& it: pairs){ u.emplace_back(it.first); t.emplace_back(it.second); } } int main(){ //vectors std::vector<int> v1 = {0, 5, 5, 2, 10}; std::vector<int> v2 = {0 ,2, 6, 20, 5}; //zip vectors auto pairs = zip(v1,v2); //sort them std::sort(pairs.begin(),pairs.end(),std::greater<>()); //unzip them v1.clear(); v2.clear(); unzip(pairs,v1,v2); //print std::cout << '\n'; for (auto i: v1) std::cout << i << ' '; std::cout << '\n'; for (auto i: v2) std::cout << i << ' '; std::cout << '\n'; } 
+9
source

Well, I don’t want it to be effective or not, but it demonstrates how to do it with std::generate , std::sort and std::transform , with some extra seasoning from mutable lambdas, and iterators.

 #include <algorithm> #include <iostream> int main() { std::vector<int> v1={0, 5, 5, 2, 10}, v2 = {0, 2, 6, 20, 5}; std::vector<int> index; index.resize(5); std::generate(index.begin(), index.end(), [n=0] () mutable { return n++; }); std::sort(index.begin(), index.end(), [&] (auto &a, auto &b) { return v2[b] < v2[a]; }); std::vector<int> v1_out, v2_out; std::transform(index.begin(), index.end(), std::back_insert_iterator<std::vector<int>>(v1_out), [&] (auto a) { return v1[a]; }); std::transform(index.begin(), index.end(), std::back_insert_iterator<std::vector<int>>(v2_out), [&] (auto a) { return v2[a]; }); for (auto n: v1_out) std::cout << n << ' '; std::cout << std::endl; for (auto n: v2_out) std::cout << n << ' '; std::cout << std::endl; } 
+3
source

Thanks so much for all your answers. I found a simple way to achieve the same effect, and the idea comes from this answer .

1. First, I used all the code from the answer that I linked, so this:

 template <typename T> vector<size_t> sort_indexes(const vector<T> &v) { // initialize original index locations vector<size_t> idx(v.size()); for (size_t i = 0; i != idx.size(); ++i) idx[i] = i; // sort indexes based on comparing values in v sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) { return v[i1] >= v[i2]; }); return idx; } 

2. Then I performed a function that would sort the first and second vector using the third. To achieve this, I had to create time vectors for the first vector, the second for the second and two for the last.

Why two ? Because I have to remember the sorted indices of the third vector, and I need one temporary one, to which I will push the elements of the original third vector according to the sorted indices.

  void SortByIndexes(vector<int>& Pi,vector<int> &Wi,vector<int>& PidivWi) { vector<int> Pitemp, Witemp, PidivWitemp,SortedIndexes; for (auto i : sort_indexes(PidivWi)) { SortedIndexes.push_back(i); } for (auto i : SortedIndexes) { Pitemp.push_back(Pi[i]); Witemp.push_back(Wi[i]); PidivWitemp.push_back(PidivWi[i]); } swap(Pi, Pitemp); swap(Wi, Witemp); swap(PidivWi,PidivWitemp); } 

3. After sorting, they simply change the sorted vectors with the original ones. Done.

Thanks to all the guys.

+1
source

All Articles