C ++根据double </t>的向量对<t>的矢量进行排序

时间:2011-05-03 16:09:36

标签: c++

我想根据double的向量对T的向量进行排序。也就是说,如果我有

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

如果a{t1, t2, t3, t4}b{3, 1, 5, 2},我想获取{t2, t4, t1, t3}

我不知道如何声明模板。我正在尝试像

这样的东西
template<vector<class T>> vector<T> sortByArray(vector<T> a, vector<double>b)

我也不知道如何编写函数体。

感谢。

编辑:这是我的算法的用法。我说不对。

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

我想对“点”的矢量和“点”矢量的矢量使用相同的模板:

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

错误是

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
          ]

6 个答案:

答案 0 :(得分:2)

您应该做的是创建一个structclass,如下所示:

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;

}

然后,您创建这些dataPair类型

的向量
{
    // 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)

}

编辑:有一些拼写错误

EDIT2:你也可以用仿函数来提高效率,但这是基本的想法。

EDIT3:Using functors with sort is described very nicely here. See where they use the functor myclass in which they overload operator(). This allows compile-time optimizations to be made (because from std::sort's perspective the sorting criterion is a template type)

答案 1 :(得分:0)

我能想到的最简单的方法是,如果你只是在你的T类声明中加入了double,并将它用作你的排序参数。很抱歉,如果我的模板语法不是很好,那么自从我使用它们已经有一段时间了:

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

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

答案 2 :(得分: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());

答案 3 :(得分:0)

如果您需要针对该问题的通用解决方案,请在此处查看其中一个答案中的拉链模板: number of matches in two sequences with STL

你需要一些接近拉链的东西 - 一些将两个序列拉成一个的实体。

答案 4 :(得分:0)

这是一个通用解决方案 - 一个将索引向量返回到数组的函数。您可以在ab上使用这些索引,以按排序顺序获取这些索引。

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

P.S。我现在已经测试了这个代码,它可以运行。

答案 5 :(得分:0)

如果你想同时对两个向量进行排序,你应该创建一个std :: vector的std :: vector(比如c)。 第一个组件必须是要正常排序的组件,第二个组件必须是相应排序的组件。

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

希望这有帮助。