【问题标题】:vector pair sorting by the difference of the pair elements向量对按对元素的差异排序
【发布时间】:2017-08-14 23:44:58
【问题描述】:

在 C++ 中有什么方法,可以根据对值的差异对我进行排序。例如,假设我有 4 对

1 3, 
5 6, 
2 3,
12 5,

所以,对的差异是 2 1 1 7,如果我按降序排序 排序后的向量将是,

12 5,
1 3,
5 6,
2 3,

我希望你明白我的问题是什么。有没有办法以这种方式对元素进行排序?

我尝试过这种方式来根据第一个或第二个元素对元素进行排序。但这不是我的问题。我的问题是我需要根据差异进行排序。

bool sortinrev(const pair<int,int> &a, const pair<int,int> &b){
    return(a.first > b.first) ;
}


int main()
{
    vector< pair <int,int> > pq;
    for(int i=1; i<=4; i++){
        int x,y;
        cin >> x >> y;

        pq.push_back(make_pair(x,y));
    }

    sort(pq.begin(), pq.end(), sortinrev);

    for(int i=0; i<4; i++){
        cout << pq[i].first << " " << pq[i].second << endl;
    }


    return 0;
}

【问题讨论】:

  • sort function c++ 可以将函数指针作为参数。只需向它传递一个按您想要的方式比较配对的函数。
  • 我只知道如何根据第一个元素或第二个元素进行排序。由于我不知道如何根据差异进行排序,所以我发布了知道方法。然后我会尝试解决我真正的问题。
  • 您可以将compare 变量传递给sort() 方法。请参阅@scohe001 在他的评论中的链接。
  • 实际上有很多方法,因为这是计算问题,而 C++ 强大到足以实现几乎任何东西(尽管有时需要时间)。在这种特殊情况下,C++ 提供了对相当简短和优雅的解决方案std::sort 的内置支持(并使用比较器变体,如 CoryKramer 的答案所示)。但是问题“C++ 中有什么方法吗?” 通常会自动回答“是”,除非你有一些非计算问题,或者一些非常低级的操作系统/固件。
  • @YeasinRahaman “最好”的方式是什么?短源?短二进制?最棒的表演?等等......在这种情况下你不能拥有所有这些,下面的答案是合理的妥协(简单的源,以预期的方式重新使用 C++ stdlib,合理的性能)。

标签: c++ sorting


【解决方案1】:

如果你的容器是

std::vector<std::pair<int, int>> data;

你可以把它排序为

std::sort(std::begin(data),
          std::end(data),
          [](std::pair<int, int> const& lhs, std::pair<int, int> const& rhs)
          {
              return std::abs(lhs.first - lhs.second) < std::abs(rhs.first - rhs.second);
          });

如果您想在升序和降序之间切换,只需相应地从 &lt; 切换到 &gt;

【讨论】:

  • 您的代码非常适合这种情况,但是如果 OP 不知道如何查找并找到这个排序函数,我怀疑他会理解 lambdas。也许添加一个解释?还是让比较器成为自己的功能?
【解决方案2】:

标准库提供了一个数据结构std::pair 和一个排序算法std::sort,您可以将定义顺序的自定义比较传递给它们。请参阅以下代码,该代码定义了一个比较器,该比较器采用两个 std::pair&lt;int,int&gt; 并根据它们的“绝对差异”进行比较,以及如何使用它调用 std::sort 的代码。希望能帮助到你。

#include <iostream>
#include <vector>

int main()
{
    std::vector<std::pair<int,int> > v = {
        {1, 3},
        {5, 6},
        {2, 3},
        {12, 5}
    };

    // sort using a custom function object
    struct {
        bool operator()(const std::pair<int,int> &a, const std::pair<int,int> &b) const
        {
            return ( abs(a.first-a.second) > abs(b.first-b.second));
        }
    } differenceIsGreater;
    std::sort(v.begin(), v.end(), differenceIsGreater);
    for (auto a : v) {
        std::cout << "(" << a.first << "," << a.second << ")" << std::endl;
    }

    return 0;
}

输出:

(12,5)
(1,3)
(5,6)
(2,3)

【讨论】:

    【解决方案3】:

    std::sort 有一个需要比较可调用的重载。

    template< class RandomIt, class Compare >
    void sort( RandomIt first, RandomIt last, Compare comp );
    

    因此,您可以传递一个 lambda(或其他函数)作为第三个参数,以任何您想要的方式进行比较。

    来自 cppreference.com:

    comp     -   comparison function object (i.e. an object that satisfies the     requirements of Compare) which returns ​true if the first argument is less than (i.e. is ordered before) the second. 
    The signature of the comparison function should be equivalent to the following:
    
    bool cmp(const Type1 &a, const Type2 &b);
    
    The signature does not need to have const &, but the function object must not modify the objects passed to it.
    The types Type1 and Type2 must be such that an object of type RandomIt can be dereferenced and then implicitly converted to both of them. ​
    

    所以,例如

    sort(begin(myvect), end(myvect), [](auto p) { /* comparison code */ });
    

    (需要 c++14,您可能需要根据您的编译器版本进行修改)

    【讨论】:

      猜你喜欢
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多