我有一组原始数据类型,需要通过某种ID来跟踪。
我正在寻找一种数据结构,让我可以保持它们的紧密包装,并且需要根据需要增加收藏。
C ++ std :: vector将是一个完美的解决方案,除了当它删除一个元素时,一些索引可以被改变,所以我不能再通过它的索引引用一个元素。我也考虑过地图,但它没有紧密包装。
我的解决方案是重写std :: vector,例如当删除条目时,条目被标记为“脏”,当需要新条目时,它可以尝试重用&#39脏'条目,如果不可能,只需增长为std :: vector。
但我的问题似乎很普遍,我相信有人遇到过它。我是否需要重新发明轮子或有人指向另一个方向?
答案 0 :(得分:2)
您可以使用vector<boost::optional<T>>
。
删除项目:
vec[val.id] = boost::none; // now this slot is empty
添加项目:
auto it = std::find(vec.begin(), vec.end(), boost::none);
if (it == vec.end()) {
val.id = vec.size(); // or however
vec.push_back(val);
}
else {
// this is an empty slot, overwrite it
val.id = std::distance(vec.begin(), it);
*it = val;
}
为了提高效率,您还可以在擦除时保留一个单独的免费索引列表 - 但这只是在一般想法之上的优化。
答案 1 :(得分:0)
您想要跟踪已删除(在您的说法中为“脏”)条目通常已完成,并称为使用“免费列表”。
另一个想法是简单地使用指针(每个数据的地址)作为ID。
答案 2 :(得分:0)
我已经晚了,但是如果用要删除的元素交换最后一个元素并从向量的背面弹出该元素呢?免费列表也是一个很好的解决方案,但可能会根据您的工作进行过度设计。