使用 std::string 作为字典顺序的键对 unordered_map 进行排序

Posted

技术标签:

【中文标题】使用 std::string 作为字典顺序的键对 unordered_map 进行排序【英文标题】:Sorting a unordered_map with a std::string as a key in lexicographical order 【发布时间】:2017-10-24 20:41:46 【问题描述】:

上周我参加了 Catalysts 编码竞赛,现在我正在尝试使用更多高级 C++ 重新创建任务。所以我决定使用std::unordered_map,其中std::string作为键值,double作为映射类型。

数据如下所示:

N0 1.23
N1 2.45

等等。

现在的问题是我想按字符串排序。但是当尝试对更大的数字进行排序时,它总是会搞砸

N3 1.23
N10 4.56

因为1 < 3 它正在逐个字符地比较它。现在我已经尝试了std::sort 函数,但我真的不明白第三个参数是如何工作的。

我希望有人可以向我解释或知道如何解决这个问题。

以下是相关源码:

std::unordered_map <std::string, unsigned int> network;
unsigned int network_power = 1234;
std::unordered_map <std::string, double> network_percent;

for (std::pair<std::string, unsigned int> element : network) 
    double x = ((double)element.second / (double)network_power) * 100;
    x = (int)(x * 100 + 0.5) / 100.0;

    network_percent.insert(element.first, x);

最后它应该按升序输出network_percent的每个元素。

提前致谢 菲利普

PS: *** 上的其他文章我已经找到了,但是没看懂。

编辑:对不起,我写这篇文章的时候已经晚了。

到目前为止我得到的排序代码如下所示:

std::sort(network_percent.begin(), network_percent.end());

正如彼得贝克尔所说,我希望它以非字典顺序对其进行排序。所以当我得到这样的数据时:

N1 92
N9 309
N2 296
N7 106
N0 218
N3 69
N4 135
N5 68
N6 157
N8 74
N12 576

我希望它排序为:

N0 218
N1 92
N2 296
N3 69
N4 135
N5 68
N6 157
N7 106
N8 74
N9 309
N12 576

目前,当密钥中有超过 1 个数字时,它会变得混乱。我的问题是:有没有按我想要的方式排序的函数?

【问题讨论】:

您在此处显示的代码似乎没有尝试对任何内容进行排序。您可以发布您用来尝试对键/值对进行排序的具体代码吗? N10 按字典顺序排在 N3 之前。你想要的是不是字典顺序的东西。您可以编写一个比较函数供std::set 使用,但首先您必须准确描述该函数应该做什么。给出两个或三个样本值并不能做到这一点。 【参考方案1】:

无序集和映射不会对任何内容进行排序。它们是散列容器,仅依赖于键的operator==(具有相同散列的所有键都将保存在称为存储桶的连续内存区域中)。未指定键的顺序。

散列容器可以非常快速地找到容器内是否有东西,但没有排序。如果要排序,则必须将network_percent的类型替换为简单的std::map

std::stringoperator&lt; 是按照字典顺序实现的,因此,您无需在此处执行任何其他操作即可获得预期的行为。

注意:你没有注意到为什么unordered_map 被称为unordered 吗? :)

【讨论】:

以上是关于使用 std::string 作为字典顺序的键对 unordered_map 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

根据键对 Python 字典进行排序? [复制]

按以某个字符串开头的键对字典进行切片

添加键的值并按在 Python 中的字典列表中出现的键对其进行排序

如何使用 std::string 作为 QHash 的键?

使用 std::string 作为 std::map 的键

在 C# 中按名称和日期作为键对字典进行排序? [复制]