C++ 为什么STL集合覆盖具有相同值的对
我可以使用answer按值降序对无序地图进行排序 但是,为同一作业使用集合失败:C++ 为什么STL集合覆盖具有相同值的对,c++,c++11,stl,C++,C++11,Stl,我可以使用answer按值降序对无序地图进行排序 但是,为同一作业使用集合失败: #include <set> #include <functional> #include <iostream> using namespace std; typedef pair<string, int> Pair; typedef function<bool(Pair, Pair)> Comparator; Comparator De
#include <set>
#include <functional>
#include <iostream>
using namespace std;
typedef pair<string, int> Pair;
typedef function<bool(Pair, Pair)> Comparator;
Comparator DescendingSortComparator = [](Pair pair1, Pair pair2) {
return pair1.second > pair2.second;
};
void SortHashTableByValueDescending(unordered_map<string, int> hashTable) {
set<Pair, Comparator> orderedSet(hashTable.begin(), hashTable.end(), DescendingSortComparator);
for (auto element : orderedSet)
cout << element.first << ": " << element.second << endl;
}
有人能告诉我为什么set(可能)会覆盖具有相同值的对吗?这些对的键无论如何都是不同的。与:
set是一个关联容器,它包含一组已排序的
唯一的键类型的对象
根据比较器,集合中只能存储一个带有固定第二个元素的单个std::对。请参阅std::set
的ofCompare
功能
在标准库使用比较概念的任何地方,唯一性都是通过使用等价关系来确定的。在不精确的术语中,如果两个对象a和b的比较都不小于另一个,则认为它们是等效的:!公司(a、b)和&!薪酬(b,a)
这意味着相等的数字将被视为等效的,而不会复制到您的orderedSet
使用
如果您想保留它们,因为它认为这两个元素是相同的,为什么不使用
std::sort
?您的比较器只考虑unordered\u map
的值,而不考虑键。感谢您的参考,我无法找到此信息。关于如何使用set使其工作,有什么想法吗?我知道排序是可能的,但我仍然想看看这种方法是否可以作为一种替代方法。当比较对的第二个元素相等时,可以按第一个元素进行额外排序。谢谢,将比较函数更改为“return pair1.second>pair2.second | |(pair1.second==pair2.second&&pair1.first>pair2.first)”修复了它。尽管如此,我还是不明白这有什么帮助,你能详细说明一下吗?你的答案是错误的,pair1.second>=pair2.second
不是一个有效的比较器。从数学上讲?在同等情况下,情况并非如此。。但我认为这就是您希望覆盖比较函数的原因:实现自定义行为。@佩吉不幸的是,我以前尝试过它,但由于与埃德加·罗基恩回答的相同原因,我出现了运行时错误。它至少必须是不可撤销的。@佩吉,谢谢。毕竟我就是这么做的。您可以在错误消息后面看到部分注释:)
void Test_SortMap()
{
unordered_map<string, int> CountTable;
CountTable["word"] = 1;
CountTable["spark"] = 15;
CountTable["the"] = 2;
CountTable["mail"] = 3;
CountTable["info"] = 3;
CountTable["sandwich"] = 15;
SortHashTableByValueDescending(CountTable);
}
spark: 15
info: 3
the: 2
word: 1
Comparator DescendingSortComparator = [](Pair pair1, Pair pair2) {
if (pair1.second == pair2.second)
return pair1.first > pair2.first;
else return pair1.second > pair2.second;
};