用于搜索和排序的最佳容器

时间:2011-08-22 18:11:51

标签: c++ stl

我有一个用于存储日志数据的纯虚拟类。此类包含两条信息:std::string id(唯一)和int64_t time(允许重复),包含getId()getTime()个函数。创建日志条目后,它们将进入容器,在应用程序终止时,日志消息将写入文件。

随着程序的继续,我可能想要更新日志条目,因此我需要搜索id以找到要更新的正确条目。关机时,我希望以time顺序记录结果。

我想到将对象存储在std::mapid作为键,对象作为值以便于搜索和更新。在关闭时,创建std::multimapstd::vector以在写入之前进行排序。这是最好的方法吗?或者是否有更好的对象可以支持这两种需求?

6 个答案:

答案 0 :(得分:9)

答案 1 :(得分:5)

由于您只需要按时间排序的条目,当程序退出时,我认为您提出的解决方案是好的。

如果您需要多次按时间和ID排序的条目boost::multi_index将是一个很好的候选人。

答案 2 :(得分:1)

解决方案是拥有一对地图。跟踪map<string, entry*>map<integer, entry*>

在更新时,您只需要按id搜索,然后编辑指向的对象。从时间图中提取所有条目时,您将拥有修改后的条目。这假设条目的id和time值是不可变的。

答案 3 :(得分:1)

如果条目是按照time的顺序生成的,那么在您执行更新时time不会更改可以简单地说:

  • 在生成std::vector<entry*>(或std::list<entry*>)时添加条目。
  • 并将其添加到std::map<std::string, entry*>(或std::unordered_map<std::string, entry*>)。

map允许在更新期间快速搜索。当要将条目转储到文件时,只需按顺序遍历std::vector

(有些变体可以为您节省一些堆分配,例如:std::vector<entry>std::map<std::string, std::vector<entry>::size_type>,其中size_type是向量元素的索引。)< / em>的

但是,如果您还需要更新time,我认为您无法避免使用std::multimap而不是std::vector

- 编辑---

好的,所以你没有按顺序time,这个怎么样:

只维护一个map<string, entry>,当需要将其转储到文件中时,从中生成vector< map<string, entry>::const_iterator >并在std::sort生成time(使用比较器参数std::sort)。

考虑:

  • 您也可以使用vector<entry*>进行排序 - 这就是您的想法 没有分配任何新条目,你只是“指向” map
  • 中的条目
  • 另请注意,您可以预先保留vector 匹配map.size(),因此可以避免矢量重新分配。
  • 如果您不需要按条目ID进行实际排序,请考虑使用unordered_map(而不仅仅是普通map)来提高效果。

这比维护第二个map更便宜,但在转储到文件之前会增加延迟。根据您的性能要求,这可能是也可能不是最佳解决方案。

答案 4 :(得分:0)

stl::map会很好。如果我没记错的话,std::map是通过引擎盖下的二叉树实现的,所以只要你重载operator<运算符就应该对它进行排序。因此,要按时间戳排序地图,请覆盖operator<以比较时间戳。

答案 5 :(得分:0)

您可以将矢量用于商店条目。在创建时,您可以为每个条目分配UID,但您可以使用条目HANDLE来修改项目。 HANDLE可以是入口指针或数组索引。在这种情况下,您将在入口访问时获得O(1)复杂性。 此外,您不需要在日志输出之前进行排序。数组已按条目创建顺序排序。 更好的解决方案来创建具有合理大小的静态数组入口结构。这将消除动态内存使用。

编辑:在输出之前,您可以对此数组进行排序以按时间顺序获取条目