【问题标题】:Why does STL Set overwrite pairs with same value为什么 STL Set 会覆盖具有相同值的对
【发布时间】:2017-01-09 10:20:22
【问题描述】:

我可以使用this 答案按值降序对无序映射进行排序。

但是,对同一作业使用集合失败:

#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;
}

运行以下测试:

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

谁能告诉我为什么 set (可能)会覆盖具有相同值的对?无论如何,这些对的键是不同的。

【问题讨论】:

  • 因为它认为这两个元素是一样的
  • 你为什么不用std::sort
  • 您的比较器帐户只有 unordered_map 的值,而不是键。

标签: c++ c++11 stl


【解决方案1】:

CompareComparedefinition函数std::set

在标准库使用比较概念的任何地方,唯一性都是通过使用等价关系来确定的。用不精确的术语来说,如果两个对象 a 和 b 的比较都不小于另一个,则认为这两个对象是等价的:!comp(a, b) && !comp(b, a)。

这意味着相同的数字将被视为equivalent,而不是复制到您的orderedSet

使用

Comparator DescendingSortComparator = [](Pair pair1, Pair pair2) {
    if (pair1.second == pair2.second)
      return pair1.first > pair2.first;
    else return pair1.second > pair2.second;
};

如果你想保留它们

【讨论】:

  • 你的答案是错误的,pair1.second &gt;= pair2.second 不是一个有效的比较器。
  • 数学上?对于相同的情况,它不是......但我认为这就是你想要覆盖比较函数的原因:实现自定义行为。
  • @pergy 不幸的是,我之前尝试过,但由于与 Edgar Rokyan 回复的原因相同,我遇到了运行时错误。
  • 它至少必须是不反身的。
  • @pergy 谢谢。毕竟我就是这么做的。您可以看到错误消息后面的部分注释:)
【解决方案2】:

来自cppreference.com

std::set 是一个关联容器,它包含一个排序的集合 唯一 Key 类型的对象。

根据您的Comparator,只有一个single std::pair 具有固定的第二个元素可以存储在集合中。

【讨论】:

  • 感谢您的参考,我无法找到此信息。关于如何使用 set 使其工作的任何想法?我知道排序是可能的,但我仍然想看看这种方法是否可以替代。
  • 当比较对的 second 元素相等时,您可以额外按 first 元素排序。
  • 谢谢,将比较函数更改为“返回 pair1.second > pair2.second || (pair1.second == pair2.second && pair1.first > pair2.first)”修复了它。不过,我不明白为什么这会有所帮助,请您详细说明一下吗?
猜你喜欢
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 2016-01-23
  • 2012-10-02
  • 2011-05-08
  • 2018-01-11
相关资源
最近更新 更多