[英]c++ std::map question about iterator order
我是一个尝试使用地图的C ++新手,所以我可以获得find()方法的恒定时间查找。
问题是,当我使用迭代器遍历地图中的元素时,元素的显示顺序与它们放置在地图中的顺序不同。
如果不维护另一个数据结构,是否有一种方法可以实现按顺序迭代,同时仍然保持恒定的时间查找能力?
请告诉我。
谢谢,jbu
编辑:感谢让我知道map :: find()不是常数时间。
如果不维护另一个数据结构,是否有一种方法可以实现按顺序迭代,同时仍然保持恒定的时间查找能力?
不,那是不可能的。 为了获得有效的查找,容器将需要以有效查找的方式对内容进行排序。 对于std :: map,这将是某种类型的排序顺序; 对于std :: unordered_map,这将是一个基于密钥哈希的顺序。
在任何一种情况下,订单都将与添加订单的顺序不同。
首先, std::map
保证O(log n)查找时间。 你可能会想到std::tr1::unordered_map
。 但是,根据定义,牺牲任何顺序来获得恒定时间查找。
你必须花一些时间在它上面,但我认为你可以抨击boost::multi_index_container
来做你想做的事情。
如何使用原始顺序中的键的vector
和快速访问数据的map
?
像这样的东西:
vector<string> keys;
map<string, Data*> values;
// obtaining values
...
keys.push_back("key-01");
values["key-01"] = new Data(...);
keys.push_back("key-02");
values["key-02"] = new Data(...);
...
// iterating over values in original order
vector<string>::const_iterator it;
for (it = keys.begin(); it != keys.end(); it++) {
Data* value = values[*it];
}
当应用于键时,项目按operator<
(默认情况下)排序。
PS。 std :: map不保证恒定时间查找。
它保证了O(ln(n))的最大复杂度
我真的要......向后走。
如果要保留插入元素的顺序,或者通常要控制顺序,则需要一个您将控制的序列:
std::vector
(是的还有其他的,但默认使用这个) 您可以使用std::find
算法(来自<algorithm>
)在向量中搜索特定值: std::find(vec.begin(), vec.end(), value);
。
哦,是的,它具有线性复杂度O(N)
,但对于小型集合,它应该无关紧要。
否则,您可以按照建议开始查看Boost.MultiIndex
,但对于初学者,您可能会有点挣扎。
所以,暂时推卸复杂性问题,并提出一些有效的方法。 当您更熟悉该语言时,您会担心速度。
首先, std::map
不是常量时间查找。 它是O(log n)。 我以为我应该这样做。
无论如何,如果要使用不同的顺序,则必须指定自己的比较函数。 没有可以按插入时间排序的内置比较函数,但是,如果对象包含时间戳字段,则可以安排在插入时设置时间戳,并使用按时间戳比较。
是的,您可以创建这样的数据结构,但不使用标准库...原因是标准容器可以嵌套但不能混合。
实现例如地图数据结构没有问题,其中所有节点也按照插入顺序处于双向链表中,或者例如所有节点都在数组中的地图。 在我看来,这些结构中的一个可能是你正在寻找的(取决于你喜欢哪种操作快),但是使用标准容器构建它们都不是很容易,因为每个标准容器( vector
, list
, set
, ...)希望成为访问包含元素的唯一方法。
例如,我发现在许多情况下有用的节点同时存在于多个双向链表中,但你不能使用std::list
来做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.