使用另一个向量以非递增顺序对一个向量进行排序

时间:2016-05-03 22:16:55

标签: c++ c++11 stl c++14

这意味着当我以非递增顺序对v2进行排序时,v1应如下所示:

向量看起来如下。

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

输出:

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

我试图解决混合std::sort和lambdas的问题。 这就是为什么我读了几个关于std::sort的问题,没有答案可以解决类似我的问题,所以这就是我要问的原因。

我对包含它的用法或C ++ 11和C ++ 14的其他功能的答案特别感兴趣。

这不是一个问题:

“我完全不知道该怎么做。”

我知道如何使用C ++ 98实现输出,但我想知道是否有更高效,更漂亮的方法。

非常感谢你的帮助:)。

3 个答案:

答案 0 :(得分:9)

您可以zipsortunzip

#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';

} 

答案 1 :(得分:3)

好吧,如果这样做有效或不高效,我不会这样做,但这会演示如何使用std::generatestd::sortstd::transform执行此操作,并添加一些额外的调料来自mutable lambdas和迭代器。

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

答案 2 :(得分:1)

非常感谢您的所有答案。我找到了一种实现相同效果的简单方法,这个想法来自this answer

1。 首先,我使用了我链接的所有代码,所以它是:

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.然后我做了一个函数,它将使用第三个对第一个和第二个向量进行排序。为了实现它,我必须为第一个向量创建一个临时向量,一个用于第二个向量,并且两个最后一个。

为什么两个 因为我必须记住第三个向量的排序索引,我需要一个临时的,我将根据排序的索引推送原始第三个向量的元素。

 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。排序后只需将已排序的矢量与原始矢量交换。 完成。

谢谢大家。