Skip to main content
Tweeted twitter.com/StackCodeReview/status/1599916539645501440
edited tags
Link
AlexV
  • 7.4k
  • 2
  • 24
  • 47
Source Link

Sorting multiple vectors based on a reference vector

I am trying to sort vectors based on a reference vector. First I am getting the indexes for the reference vector and then using that I am doing inplace sorting for the rest of the vectors.

#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm>

using iter = std::vector<int>::iterator;
using order_type = std::vector<std::pair<size_t, iter>>;

void create_permutation(order_type &order)
{
        struct ordering {
                bool operator ()(std::pair<size_t, iter> const& a, std::pair<size_t, iter> const& b) {
                        return *(a.second) < *(b.second);
                }
        };

        std::sort(order.begin(), order.end(), ordering());
}

void reorder(std::vector<int> &vect, order_type index)
{
        for (int i=0; i< vect.size(); i++)
        {
                while (index[i].first != i)
                {
                        int  old_target_idx  = index[index[i].first].first;
                        int old_target_v  = vect[index[i].first];

                        vect[index[i].first] = vect[i];
                        index[index[i].first].first = index[i].first;

                        index[i].first = old_target_idx;
                        vect[i]   = old_target_v;
                }
        }
}

template<typename... argtype>
void sort_from_ref(argtype... args);

template<typename T, typename A, typename... argtype>
void sort_from_ref(order_type order, std::vector<T,A> &vect, argtype &&...args)
{
        reorder(vect, order);
        sort_from_ref(order, std::forward<argtype>(args)...);
}

template<>
void sort_from_ref(order_type order, std::vector<int> &vect) {
        reorder(vect, order);
}

int main()
{
        size_t n = 0;
        std::vector<int> vect_1{ 1, 0, 2, 3 };
        std::vector<int> vect_2{ 100, 200, 300, 400 };
        std::vector<int> vect_3{ 100, 200, 300, 400 };
        std::vector<int> vect_4{ 400, 200, 3000, 4000 };
        std::vector<int> vect_5{ 500, 200, 360, 400 };
        order_type order(vect_1.size());

        for (iter it = vect_1.begin(); it != vect_1.end(); ++it) {
                order[n] = std::make_pair(n, it);
                n++;
        }
        create_permutation(order);
        sort_from_ref(order, vect_2, vect_3, vect_4, vect_5);

        {
                std::vector<int> test{200, 100, 300, 400};
                assert(vect_2 == test);
        }
        {
                std::vector<int> test{200, 100, 300, 400};
                assert(vect_3 == test);
        }
        {
                std::vector<int> test{200, 400, 3000, 4000};
                assert(vect_4 == test);
        }
        {
                std::vector<int> test{200, 500, 360, 400};
                assert(vect_5 == test);
        }

        return 0;
}