首页 > 解决方案 > 如何使用自定义重复判断功能进行设置?

问题描述

我想使用 STL 设置为:

  1. 将 astruct插入此集合中,例如struct {int id, string info};
  2. 对于每个插入,如果 id 存在,则不要插入
  3. 使元素排序

我尝试了以下代码:

#include <iostream>
#include <set>
using namespace std;
struct song
{
    int m_id;
    int m_hot;
    song(int id,int hot)
    {

        this->m_id = id;
        this->m_hot = hot;
    }
    bool operator<(const struct song & right)const
    {
        if(this->m_id == right.m_id) {     // remove duplicated
            return false;
        }
        if(this->m_hot != right.m_hot)
        {
            return this->m_hot > right.m_hot;
        }
        else
        {
            return this->m_id > right.m_id;
        }
    }
};
int main()
{
    std::set<song> mySet;
    song s1(10,100);
    song s2(40,700);
    song s3(40,300);
    song s4(30,200);
    song s5(300,200);
    song s6(300,900);
    mySet.insert(s1);
    mySet.insert(s2);
    mySet.insert(s3);
    mySet.insert(s4);
    mySet.insert(s5);
    mySet.insert(s6);
    for(auto it:mySet)
    {
        std::cout<<"id:"<<it.m_id<<",hot:"<<it.m_hot<<std::endl;
    }
}

输出是:

id:300,hot:900
id:40,hot:700
id:300,hot:200
id:30,hot:200
id:10,hot:100

可以看到,id 40 成功删除了复制,但是 300 失败了。我认为 id 300 部分不应该出现两次,有人可以帮我吗?

标签: c++stlset

解决方案


operator<不满足严格的弱排序,您的要求不能这样表达。

问题是您有两个键,m_id(用于唯一性)和m_hot(用于排序)。您不能选择仅按m_hot. 您始终必须对两者进行排序(并忽略等效比较元素),并且您只能选择优先级。因此,您无法在{id=0, hot=0}和之间建立等价关系{id=0, hot=1}

^ 如果你的比较器不能写成std::tie(lhs.keys...) < std::tie(rhs.keys...),那就不好了。

目前,我只能考虑m_hot在您需要的地方推迟排序(通过复制到 astd::vector并对其进行排序或插入到std::set具有不同比较器的 a 中)。


推荐阅读