C ++ Sort vector from <T> according to double vector

I want to sort the vector T according to the double vector. That is, if I have

vector<T> a;
vector<double>b;

If a- {t1, t2, t3, t4}, but b- {3, 1, 5, 2}, I want to receive {t2, t4, t1, t3}.

I do not know how to declare a template. I'm trying something like

template<vector<class T>> vector<T> sortByArray(vector<T> a, vector<double>b)

And I don’t even know how to write a function body.

Thank.

EDIT: This is a use of my algorithm. I do not understand.

template <typename T> struct dataPair
{
    dataPair(double s, T o) 
    : m_sortData(s)
    , m_otherData(o)
    {

    }

    bool operator< (const dataPair &rhs) { return (m_sortData < rhs.m_sortData); }

    double m_sortData;
    T m_otherData;

}



  template <class T> vector<T> sortByArrayStuff(vector<T> objects, vector<double> sortNumber) {
    vector<dataPair<T>> v;
    for (unsigned int i = 0; i < objects.size(); i++) {
        v.push_back(dataPair<T>(objects[i], sortNumber[i]));
    }
    sort(v.begin(), v.end());
    vector<T> retVal;

    for (unsigned int i = 0; i < objects.size(); i++) {
        retVal.push_back(dataPair<T>(objects[i], sortNumber[i]));
    }
    return retVal;
};

I want to use the same template for Point vectors and Point vectors:

vector<double> sortedAreas;
vector<Point> sortedPoints = sortByArray<vector<Point>>(points, sortedAreas);
vector<vector<Point>> sortedContours = sortByArray<vector<vector<Point>>>(contours, sortedAreas);

Error

cannot convert parameter 1 from 'dataPair<T>' to 'cv::Point &&'
          with
          [
              _Ty=cv::Point
          ]
          and
          [
              T=cv::Point
          ]
          Reason: cannot convert from 'dataPair<T>' to 'cv::Point'
          with
          [
              T=cv::Point
          ]
+3
source share
6 answers

What you need to do is create structeither classas follows:

template <typename T> struct dataPair
{
    dataPair(double s, T o) 
    : m_sortData(s)
    , m_otherData(o)
    {

    }

    bool operator< (const dataPair &rhs) { return (m_sortData < rhs.m_sortData); }

    double m_sortData;
    T m_otherData;

}

Then you create a vector of these dataPairtypes

{
    // your code ...
    // that assumes b is is a std::vector<YourType>

    // create vector and populate it
    std::vector<dataPair<YourType>> v;
    v.push_back(dataPair<YourType>(a[0],b[0]));
    v.push_back(dataPair<YourType>(a[1],b[1]));
    v.push_back(dataPair<YourType>(a[2],b[2]));
    v.push_back(dataPair<YourType>(a[3],b[3]));

    std::sort(v.begin(),v.end());

    // your code (now they will be sorted how you like in v)

}

EDIT: There were some typos

EDIT2: , .

EDIT3: . , myclass, operator(). ( std::sort )

+2

, , , double T . , , , ive :

class YourClass
{
  //Some stuff...
  double sortVal;
};

bool std::less<YourClass>(YourClass left, YourClass  right)
{
   return left.sortVal < right.sortval;
}
0

- , . . , , . 2 , :

// This function basically does the reverse of a transform.  Whereas transform takes
// two inputs and by some method merges them into one, this function takes one input
// and by some method splits it in two.
template<typename InIt, typename Out1It, typename Out2It, typename Fn>
void fork_transform(InIt ibegin, InIt iend, Out1It o1begin, Out2It o2begin, Fn fork)
{
    while(ibegin != iend)
    {
        fork(*ibegin, *o1begin, *o2begin);
        ++o1begin;
        ++o2begin;
        ++ibegin;
    }
}

template<typename ItPrimary, typename ItSecondary>
void simul_sort(ItPrimary begin1, ItPrimary end1, ItSecondary begin2)
{
    typedef std::iterator_traits<ItPrimary>::value_type T1;
    typedef std::iterator_traits<ItSecondary>::value_type T2;

    typedef std::multimap<T1,T2> Map_t;
    typedef Map_t::value_type Pair_t;

    Map_t m;

    // this was necessary for me because of a bug in VC10, see my most recent question
    auto MakePair = [](const T1 & first, const T2 & second) { return std::make_pair(first,second); };
    std::transform(begin1, end1, begin2, std::inserter(m,m.begin()), MakePair);

    auto Fork = [](const Pair_t & p, T1 & first, T2 & second) { first = p.first; second = p.second; };
    fork_transform(m.begin(), m.end(), begin1, begin2, Fork);
}

. , :

simul_sort(b.begin(), b.end(), a.begin());
0

, : STL

- - - - , .

0

Here's a general solution - a function that returns an index vector to an array. You can use these indexes on any of yours aor bto get them in sorted order.

template<class RandomAccessIterator>
struct IndirectCompare : public std::binary_function<size_t, size_t, bool>
{
    IndirectCompare(RandomAccessIterator first) : m_first(first)
    {
    }
    bool operator()(const size_t &left, const size_t &right)
    {
        return *(m_first + left) < *(m_first + right);
    }
    RandomAccessIterator m_first;
};

template<class RandomAccessIterator>
std::vector<size_t> ordered_index(RandomAccessIterator first, RandomAccessIterator last)
{
    size_t n = last - first;
    std::vector<size_t> result;
    result.reserve(n);
    for (size_t i = 0;  i < n;  ++i)
        result.push_back(i);
    IndirectCompare<RandomAccessIterator> comp(first);
    std::sort(result.begin(), result.end(), comp);
    return result;
}

PS I tested this code now and it works.

0
source

If you want to sort two vectors at the same time, it is better to create std :: vector (say c) std :: pair. The first component should be the one that should be sorted normally, and the second should be sorted accordingly.

std::vector<std::pair<double, T>> c;
std::sort(c.begin(), c.end());

Hope this helps.

0
source

All Articles