繁体   English   中英

关于迭代器顺序的c ++ std :: map问题

[英]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)。 我以为我应该这样做。

无论如何,如果要使用不同的顺序,则必须指定自己的比较函数。 没有可以按插入时间排序的内置比较函数,但是,如果对象包含时间戳字段,则可以安排在插入时设置时间戳,并使用按时间戳比较。

地图不是用于按某种顺序放置元素 - 使用向量。

如果你想在地图中找到某些东西,你应该使用[操作员]按键“搜索”

如果您同时需要:迭代和按键搜索,请参阅此主题

是的,您可以创建这样的数据结构,但不使用标准库...原因是标准容器可以嵌套但不能混合。

实现例如地图数据结构没有问题,其中所有节点也按照插入顺序处于双向链表中,或者例如所有节点都在数组中的地图。 在我看来,这些结构中的一个可能是你正在寻找的(取决于你喜欢哪种操作快),但是使用标准容器构建它们都不是很容易,因为每个标准容器( vectorlistset , ...)希望成为访问包含元素的唯一方法。

例如,我发现在许多情况下有用的节点同时存在于多个双向链表中,但你不能使用std::list来做到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM