c++ - 是否可以使用 std::pair 作为 std::set 的键而没有任何重复的每个元素?

标签 c++ c++11 stl

我尝试使用结构中的两个整数作为键将结构存储在 std::set 中。 我知道可以使用 std::pair 作为 std::set 的键。

struct TYPE{
  pair<int, int> nums;
  ... // some other things

  TYPE(){}
  TYPE(int first, int second) { nums = make_pair(first, second); }
  bool operator<(const TYPE &rhs) const{
    return nums < rhs.nums;
  }
};
set<TYPE> nums_set;
nums_set.insert(TYPE(1, 2));
nums_set.insert(TYPE(1, 4));
nums_set.insert(TYPE(5, 2));
// size of set : 3, (1,2)(1,4)(5,2)
auto it = nums_set.find(TYPE(1, 2)); // find return (1,2)

但是,我想要可搜索且没有重复的 std::set,无论 std::pair 中元素的顺序如何。 像这样:

nums_set.insert(TYPE(1, 2));
nums_set.insert(TYPE(1, 4)); // failed. duplicate 1
nums_set.insert(TYPE(4, 2)); // failed. duplicate 2
nums_set.insert(TYPE(4, 1)); // failed. duplicate 1
nums_set.insert(TYPE(3, 4));
// size of set : 2, (1,2)(3,4)
auto it = nums_set.find(TYPE(2, 7));  // find return (1,2).

到目前为止最简单的解决方案是使用 std::vector 代替,并在插入 vector 之前进行重复检查,如下所示:

auto fn = [](const TYPE& e, const TYPE&& t){
    return e.nums.first == t.nums.first ||
            e.nums.first == t.nums.second ||
            e.nums.second == t.nums.first ||
            e.nums.second == t.nums.second;
};
vector<TYPE> nums_vec;
nums_vec.push_back(TYPE(1, 2));
if(nums_vec.end() == find_if(nums_vec.begin(), nums_vec.end(), 
  bind(fn, placeholders::_1, TYPE(1,4))))
{  nums_vec.push_back(TYPE(1,4)); }

但是,我觉得对每个插入都执行此操作以避免重复并不是一个好主意。 所以,我的问题是,是否也可以使用 std::set 来实现这些功能?

最佳答案

用于集合的比较必须满足 Compare命名要求。这些要求之一是导出的等价关系的传递性:

If equivalent(a,b) and equivalent(b,c) then equivalent(a,c).

具体案例:

  • a{1,2} , b{1,4} ,和c{3,4} .
  • 传递性: if {1,2}相当于 {1,4}{1,4}相当于 {3,4}然后{1,2}相当于 {3,4} .

另一种表达方式 X相当于 YX 的存在在你的设置中可以防止 Y被添加。您想要{1,2}防止{1,4}从被添加到集合中。您想要{1,4}防止{3,4}从被添加到集合中。为了具有所需的传递性,需要{1,2}防止{3,4}避免被添加到集合中,这是您想要的。

不,您的目标不能仅通过集合使用的顺序来实现。

关于c++ - 是否可以使用 std::pair 作为 std::set 的键而没有任何重复的每个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66236104/

相关文章:

c++ - Xeon Phi 上每 60 个线程 pthread_create() 失败(无效参数)

c++ - 无法从 const T 转换为 const T&

c++ - Shell使用特定的工作目录执行cmd提示符

c++ - 检查 C++ 类是否公开继承自带有匿名参数的模板类

c++ - C++中c_str()的线程安全

c++ - 查找最小堆中的最大元素

c++ - 如何获得 std::map 的真正分配器?

c++ - 在 win32 API 中将 int 转换为字符串

c++ - basic_socket_acceptor 接口(interface)在 boost 1.66 中发生了变化……这是一个错误吗?

c++ - 在具有菱形继承和虚拟基类的类中调用函数的策略