混合矢量/列表容器
Hybrid vector/list container?
我需要一个同时具有向量和列表属性的容器。我需要快速随机访问容器中的元素,但我也需要能够在不移动其他元素的情况下移除容器中间的元素。我还需要能够迭代容器中的所有元素,并一目了然(无需迭代)容器中有多少元素。
经过一番思考,我已经找到了如何创建这样一个容器,使用向量作为基本容器,并将实际存储的数据包装在一个结构中,该结构还包含记录元素是否有效的字段,以及指向向量中下一个/上一个有效元素的指针。再加上一些重载之类的,听起来应该是相当透明的,并满足我的要求。
但在我真正创建另一个容器之前,我很好奇是否有人知道实现这一功能的现有库?我宁愿使用有效的东西,也不愿花时间调试自定义实现。我已经浏览了Boost库(我已经在使用它),但在那里没有找到这个。
如果顺序无关紧要,我只需要使用一个将整数映射到指针的哈希表。std::tr1::unordered_map<int, T *>
(或者如果C++0x正常则为std::unordered_map<int, unique_ptr<T>>
)。
哈希表的元素可以四处移动,这就是为什么您需要使用指针,但它将支持非常快速的插入/查找/删除。迭代也很快,但元素会以不确定的顺序出现。
或者,我认为您可以将自己的想法实现为std::vector
和std::list
的简单组合。只需同时维护一个list<T> my_list
和一个vector<list<T>::iterator> my_vector
。要添加对象,请将其推到my_list
的背面,然后将其迭代器推到my_vector
上。(将迭代器设置为my_list.end()
,并将其递减以获得最后一个元素的迭代器。)要查找,请在向量中查找,然后取消对迭代器的引用。要删除,请从列表中移除(可以通过迭代器执行),并将向量中的位置设置为my_list.end()
。
std::list
保证删除中的元素时它们不会移动。
[更新]
我感觉很有动力。实现的第一关:
#include <vector>
#include <list>
template <typename T>
class NairouList {
public:
typedef std::list<T> list_t;
typedef typename list_t::iterator iterator;
typedef std::vector<iterator> vector_t;
NairouList() : my_size(0)
{ }
void push_back(const T &elt) {
my_list.push_back(elt);
iterator i = my_list.end();
--i;
my_vector.push_back(i);
++my_size;
}
T &operator[](typename vector_t::size_type n) {
if (my_vector[n] == my_list.end())
throw "Dave's not here, man";
return *(my_vector[n]);
}
void remove(typename vector_t::size_type n) {
my_list.erase(my_vector[n]);
my_vector[n] = my_list.end();
--my_size;
}
size_t size() const {
return my_size;
}
iterator begin() {
return my_list.begin();
}
iterator end() {
return my_list.end();
}
private:
list_t my_list;
vector_t my_vector;
size_t my_size;
};
它缺少一些实施质量方面的内容。。。比如,你可能想要更多的错误检查(如果我删除同一个元素两次怎么办?),也许还需要operator[]
、begin()
、end()
的一些const
版本。但这只是一个开始。
也就是说,对于"几千个"元素,一张地图可能至少也会起到同样的作用。一个很好的经验法则是"永远不要优化任何东西,直到你的剖析器告诉。
看起来您可能想要一个std::deque。移除元素不如std::list
有效,但因为deque通常是通过使用非连续内存"块"创建的,这些块通过容器内部的额外指针数组/向量进行管理(每个"块"都是N个元素的数组),因此移除deque
内部的元素不会导致与向量相同的重新洗牌操作。
编辑:第二次,在查看了一些评论之后,虽然我认为std::deque
可以工作,但我认为std::map
或std::unordered_map
实际上会对您更好,因为它将允许您想要的数组语法索引,同时还可以快速删除元素。
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- C++11 中的混合列表初始化
- 将 lambda 函数转换为具有混合 lambda 引入器和参数列表的函子结构
- 在C++中的混合对象列表中使用相同的方法
- C - 混合默认成员初始化器和成员初始化列表 - 坏主意
- 在构造函数中混合可变参数模板和初始值设定项列表
- C++11 中的混合(列表+字典)容器
- 混合类型,可变长度参数列表(varargin,*args,..)用于C++
- c++可变模板构造函数的成员和混合的初始化列表
- 在c++ /Qt中拆分Lua函数调用的混合字符串/数字参数列表
- 在c++类中混合指向构造结构的指针——在参数列表中声明结构
- 混合矢量/列表容器