关联容器所需的比较器
Comparator needed for an associative container
我需要一std::set<std::pair<std::string, int>, Compare>
,根据它们的 int 值(以相反的顺序)比较两对,如果它们的 int 值相同,则根据它们的字符串值(以相同的顺序),但如果它们的字符串相等,那么两对被认为是相等的(无论它们的 int 值如何)。 所以我想出Compare
课是:
struct Compare {
bool operator()(const std::pair<std::string, int>& a, const std::pair<std::string, int>& b) const {
if (a.first == b.first)
return false;
if (a.second > b.second)
return true;
if (a.second < b.second)
return false;
return a.first < b.first;
}
};
测试内容
std::set<std::pair<std::string, int>, Compare> s;
s.insert({"Apple", 3});
s.insert({"Apple", 5});
工作正常(仅插入第一对)。 但
int main() {
std::set<std::pair<std::string, int>, Compare> s;
s.insert({"Ai", 14});
s.insert({"Am", 14});
s.insert({"F", 5});
s.insert({"Apple", 3});
s.insert({"Apple", 5});
}
显示{"Apple", 3}
和{"Apple", 5}
都入,我不知道为什么。 我的Compare
课上有什么逻辑错误? 它应该是什么? 我考虑使用std::map<std::string, int, Compare>
但在这种情况下,比较器只能使用键类型std::string
,这不足以满足我的规格。
我也试过:
bool operator()(const std::pair<std::string, int>& a, const std::pair<std::string, int>& b) const {
if (a.first < b.first || a.first > b.first) {
if (a.second > b.second)
return true;
if (a.second < b.second)
return false;
return a.first < b.first;
}
return false;
}
它仍然没有给出我想要的结果。
在检查了您的要求后,我得出的结论是,您比较对象的标准不符合严格周排序的要求。
假设您将以下对象插入到集合中:
std::pair<std::string, int> obj1 = {"F", 5};
std::pair<std::string, int> obj2 = {"Apple", 3};
std::pair<std::string, int> obj3 = {"Apple", 5};
s.insert{obj1);
s.insert(obj2);
s.insert(obj3);
obj1
被添加,因为集合中没有其他可以比较的东西。obj2
也被添加,因为它比较不等于obj1
。然而。自obj1.second > obj2.second
以来,集合中对象的顺序为:
obj1
obj2
现在,我们来插入obj3
.obj3 < obj1
的计算结果为true
.因此,它会在obj1
之前插入。将项目插入集合的逻辑是这样的,obj3
永远不会与obj2
进行比较。因此,您最终会得到:
obj3
obj1
obj2
这不是在std::set
中比较的工作方式。它旨在提供从最小到大的顺序。使用您的集合,您正在尝试进行 2 种不同类型的比较。
您可以按第一个整数值,其次是字符串值对其进行排序。没关系。
但是,如果一个集合中的 2 个元素比较小,则认为它们相等,如果没有,则它们比另一个元素小。
当你做第一个例子时,这两个元素恰好彼此相邻,所以比较函数将用于它们和你的a.first == b.first
情况触发,它们似乎都不比另一个小,所以它们被认为是相等的。
当你进行第二次尝试时,当你插入"Apple", 5
你的套装看起来像这样。
Ai 14
Am 14
F 5
Apple 3
Apple, 5
在这里比较小然后Am 14
,大然后F 5
,所以它永远不会与Apple 3
进行比较,但它将入两个元素之间,然后它更大更小。由于std::set
是按顺序排序的,因此就Compare
而言,其他要素已经无关紧要。
问题是第一次比较,这是错误的。删除它,它可以工作。
- std::设置自定义比较器
- C++中"std::sort"比较器的不同类型
- 将 std::set 与基于键的比较器一起使用
- 带自定义比较器的最小优先级队列
- 函数类作为比较器
- 优先级队列自定义比较器
- 什么是自定义比较器以及如何在 C++ 的排序函数中使用它?
- 没有默认构造函数作为模板参数的自定义比较器
- set_intersection使用自定义设置比较器
- 如何为集合 c++ 建立比较器
- C++复杂情况的比较器通过参数问题
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 对没有比较器或λ函数的向量进行排序?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- 用户定义的结构是否有默认C++比较器?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 使用迭代器的自定义比较器函数
- 关联容器所需的比较器
- 我们可以使用异构查找比较器对 STL 关联容器执行"partial-match"搜索吗?
- 允许指定单独比较器和排序函子的关联容器