【问题标题】:Store named items in lookup table在查找表中存储命名项目
【发布时间】:2020-06-16 04:06:27
【问题描述】:

考虑下面的类

class Person
{
     public:
          explicit Person(RegistrationNumber id, std::string const& name);

          RegistrationId id() const;

          std::string const& name() const;
          Person& name(std::string const&);

          // ...
     private:
          RegistrationNumber m_id;
          std::string m_name;
          // ...
};
  1. 现在我希望能够通过 id 找到一个人,并更新其姓名。为此,我可以使用std::set<Person, PersonIdCompare>,但如果没有const_cast,我将无法修改记录。

  2. 将 Persons 存储在 std::map<RegistrationId, Person> 中是否更好,这样可以更改记录,尽管这需要存储两次 id。

  3. 或者我应该使用地图,并从 Person 类中删除 id。但是,如果我只能访问 Person 而不是 std::pair<RegistrationNumber const, Person>,则我无法获取 id,因此这可能需要传递这些对。

什么选项最有效或最不容易出错。想一想有人为人员 ID 添加设置器的场景,这会破坏选项 1 和 2,或者将 ID 存储两次作为选项号 2。

【问题讨论】:

  • 数据集中有多少人?对于小型数据集,通过向量的线性遍历非常快。
  • @NathanOliver 我也希望能够强制不重复的条目,并且拥有不变的位置也很好。
  • 在这种情况下使用选项 2。当您已经在使用基于节点的容器时,每个对象一个额外的 int 并不多。

标签: c++ dictionary constants data-consistency


【解决方案1】:

大多数情况下,最好将所有内容都放入(可能)排序的std::vector<Person>。然后您可以对向量进行二进制搜索以查找元素。封装矢量对象的小型便利类会很有用。

您具有缓存局部性的优势(尤其是在迭代所有条目期间)。而且至少setmap (O(log n)) 的检索性能相同。然而,如果没有优化,插入会稍微差一些(O(n) 与 O(log n))。如果您进行批量插入,您可以只插入所有项目,然后对向量进行排序,从而获得设置/映射性能。

附录:如果 id 是唯一的并且升序(没有或很少有间隙),那么向量也是显而易见的选择,因为您可以只使用 id 作为索引。如果不能保证 id 是连续的,请考虑vector<optional<Person>>

【讨论】:

  • 我应该试一试。我的数据集在加载时间后也是不变的。所以加载和排序就可以了。
  • @user877329 哦,如果它是不变的并且只加载一次,那么肯定采用向量方法!
  • 虽然 std::set 需要 const_iterator 是有原因的。那就是保证不变量。因此,如果您从 std::vector 构造 LinearSet,则与该容器关联的 getter 和迭代器仍需要 const。
  • @user877329 通常是的,但是如果 id 是不变的,那么您的索引就可以了。是的,这冒着有人在五年内为 id 添加 setter 的风险,一切都崩溃了。对 m_id 的评论说 must be invariant 可能会有所帮助。此外,您可以将 m_id 设为 const。
  • 如果您使用自己的交换功能,请确保有注释解释为什么需要您自己的交换功能。没有什么比看到一段代码更让人恼火的了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 2019-09-24
  • 2016-11-18
  • 1970-01-01
  • 2019-03-31
  • 2022-01-06
  • 2015-09-30
相关资源
最近更新 更多