如何确保 std::map 是有序的

How to ensure that a std::map is ordered?

本文关键字:map std 何确保 确保      更新时间:2023-10-16

使用std::map<int, ...>如何确保在插入时迭代它将按整数键的升序进行?

你不需要做任何事情。映射将根据键的值按升序排列。

在内部,映射执行键之间的比较以对其元素进行排序。默认情况下,它使用 std::less<KEY> ,这相当于整数的bool operator<(int, int)。对于用户定义的类型,您必须选择:

  1. 实现一个bool operator<(const MyType&, const MyType&)在用户定义的类型之间实现严格的弱排序比较。如果您的类型具有自然排序,请使用此选项

  2. 提供一个实现严格弱排序的二进制函子,您可以将其作为第三个模板参数传递给映射。如果您的类型没有自然排序,或者您希望使用与std::less<Key>通过点 1 bool operator<(...)使用的排序不同的顺序构建地图,请使用此选项。

通常在幕后发生的事情是,映射被实现为自平衡二叉树,并且使用严格的弱排序在映射中放置新元素,并确定两个元素是否相等。顺便说一句,同样的逻辑适用于std::set,其中键和值是相同的。

std::map自己这样做。您不必执行任何操作。

默认情况下,它按递增顺序对键进行排序。如果您希望它按降序进行排序,请将std::greater<T>作为第三个模板参数传递给std::map

std::map<int, X>  m1;                    //sorts key in increasing order
std::map<int, X, std::greater<int>>  m2; //sorts key in decreasing order
std::map<int, X, std::less<int>> m3;     //sorts key in increasing order

第三个模板参数的默认参数是 std::less<T> ,所以上面的 m1m3 是相同的类型!

演示:

#include <iostream>
#include <map>
#include <string>
int main()
{
    std::cout << "nkeys are in increasing order: n";
    std::map<int, std::string> m1;
    m1[5] = "first insertion but higher key";
    m1[1] = "second insertion but lower key";
    for(auto const & item : m1) 
       std::cout << "{" << item.first  <<"," << item.second << "}n";
    std::cout << "nkeys are in decreasing order: n";   
    std::map<int, std::string, std::greater<int> > m2;
    m2[1] = "first insertion but lower key";
    m2[2] = "second insertion but higher key";
    for(auto const & item : m2) 
       std::cout << "{" << item.first  <<"," << item.second << "}n";
}

输出:

keys are in increasing order: 
{1,second insertion but lower key}
{5,first insertion but higher key}
keys are in decreasing order: 
{2,second insertion but higher key}
{1,first insertion but lower key}

请注意,在这两种情况下,项目都按照 std::map 的第三个模板参数指定的方式排序。输出不依赖于插入顺序,而是取决于键的顺序!

现场演示

还有不对元素进行排序的std::unordered_map

map通常实现为二叉搜索树,因此迭代器已经为您提供排序键。

如果您不关心订单,您可以使用unordered_map(从 c++11 或 boost 开始),这会让您加快订单交易速度。

相关文章: