如何确保 std::map 是有序的
How to ensure that a std::map is ordered?
使用std::map<int, ...>
如何确保在插入时迭代它将按整数键的升序进行?
你不需要做任何事情。映射将根据键的值按升序排列。
在内部,映射执行键之间的比较以对其元素进行排序。默认情况下,它使用 std::less<KEY>
,这相当于整数的bool operator<(int, int)
。对于用户定义的类型,您必须选择:
-
实现一个
bool operator<(const MyType&, const MyType&)
在用户定义的类型之间实现严格的弱排序比较。如果您的类型具有自然排序,请使用此选项 -
提供一个实现严格弱排序的二进制函子,您可以将其作为第三个模板参数传递给映射。如果您的类型没有自然排序,或者您希望使用与
std::less<Key>
通过点 1bool 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>
,所以上面的 m1
和 m3
是相同的类型!
演示:
#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 开始),这会让您加快订单交易速度。
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏