如何使用自定义重复判断函数进行设置?

时间:2019-05-12 09:01:53

标签: c++ stl set

我想使用STL设置为:

  1. struct插入到此集合中,例如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部分不应出现两次,有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

您的operator<不满足strict weak ordering,因此您的要求无法这样表达。

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

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

此刻,我只能想到在您需要的位置按m_hot推迟排序(通过复制到std::vector中并进行排序,或插入具有不同内容的std::set比较器)。