【问题标题】:std::set containing pair with custom comparatorstd::set 包含对与自定义​​比较器
【发布时间】:2013-09-12 14:53:17
【问题描述】:

我有一个vector < pair <double, int> >,其中double 代表一个人的体重,int 代表那个人的ID。

现在我需要将其转换为 set < pair < double, int > > 以根据该人的 id 删除重复项,但在向量内部我有一些精度不高的数据。

示例数据:

-----------------------
    double |   int
-----------------------
    10.234 |  1     <--
    20.123 |  2
    10.2   |  1     <--
    30.33  |  3

如我们所见,id 1 具有不同精度的权重。

使用默认比较器std::set 将导致集合中有 4 个元素,但我只需要 3 个。

集合中应该只有 1 个带有 id 1 的元素(两个竞争对手中的任何一个都可以)。

我不使用std::map 的原因是,我需要条目按特定顺序排列:我需要它们按重量排序。出于这个原因,我使用了以下比较器:

struct comp__f {
    bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const{
        if(lhs.first < rhs.first) return true;
        if(lhs.first > rhs.first) return false;
        return lhs.second > rhs.second;
    }
};

注意:问题仍然悬而未决,@Robᵩ 的回答并没有完全解决问题,但我感谢他的努力。

【问题讨论】:

  • 你需要的“特定顺序”是什么?

标签: c++ stl operator-overloading stdvector std-pair


【解决方案1】:

由于一条记录不能小于其自身或其等价的自身,因此请确保如果两条记录具有相同的 ID,无论权重如何,您的 comp 函数都会返回 false。

// Assuming that your previous comp_f was correct, here is the new one:
struct comp__f {
    bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const{
        if(lhs.second == rhs.second) return false;  // ADD THIS LINE
        if(lhs.first < rhs.first) return true;
        if(lhs.first > rhs.first) return false;
        return lhs.second > rhs.second;
    }
};

【讨论】:

  • 添加该行将重新排列元素的顺序,但集合仍然有 4 个元素。没有?
  • @Jaydeep - 不。添加该行,该集合将只有 3 个元素。 set 会观察到{10.234, 1} &lt; {10.2, 1} 是假的,{10.2, 1} &lt; {10.234, 1} 也是假的。它会正确地断定元素是相同的,并拒绝插入后一个。 (至少,如果它是拟人化的,它会这样做。)
  • @juanchopanza,你是对的,我刚刚阅读了文档。 + 我刚刚尝试过,它适用于示例示例。这里是否有任何异常行为的变化,因为我有大量数据,使用 gdb 我看到元素数量减少了,但仍然存在一些具有相同 id 的元素。我很困惑:/
  • @Jaydeep 我也很困惑。我看不出这个比较函数可以允许具有相同 id 的多个元素。您能否将您的程序缩减为显示该错误的最小程序,然后复制粘贴该小而完整的程序作为您问题的补充?
  • @Robᵩ,请用上面的比较器试试这个序列paste.kde.org/pb90c1e42,我得到两个 id = 1 的元素
【解决方案2】:

试试这个

#include<set>
#include<iostream>
using namespace std;

class CustomComparitor
{
    public:
        int operator()(const pair<double,int>& lhs, const pair<double,int>& rhs)
        {
            return lhs.second < rhs.second;
        }
};
int main()
{
    set<pair<double,int>,CustomComparitor> myset;
    myset.insert(make_pair(1.4, 2));
    myset.insert(make_pair(1.5, 2));
    myset.insert(make_pair(1.6, 1));
    myset.insert(make_pair(1.4, 3));

    for(auto itr = myset.begin(); itr!=myset.end();itr++)
    {
        cout<<itr->first<<"  "<<itr->second<<endl;
    }
    return 0;
}

【讨论】:

  • 似乎与我在 9 分钟时回答的内容非常相似。前。但事实证明 OP 需要按重量排序元素。
【解决方案3】:

我知道,我迟到了,但我遇到了类似的问题,我想我已经解决了。 Robᵩ was already on the right track,但是您的原始行也需要修改。总而言之,我想出了以下比较器:

struct comp__f {
    bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const {
        return (lhs.second != rhs.second) && (lhs.first < rhs.first),
    }
};

正如 Robᵩ 解释的那样,(lhs.second != rhs.second) 部分确保 ID 是唯一的。如果可以保证,那么您只需要使用&lt; 比较权重。因此,(lhs.first &lt; rhs.first) 确保集合中的唯一条目按其权重排序。

Code on Ideone

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2021-10-23
    相关资源
    最近更新 更多