C++:为向量中的非连续索引赋值?
Posted
技术标签:
【中文标题】C++:为向量中的非连续索引赋值?【英文标题】:C++: Assigning values to non-continuous indexes in vectors? 【发布时间】:2009-05-30 15:44:37 【问题描述】:如果我想声明一个未知大小的向量,则按索引 5、索引 10、索引 1、索引 100 的顺序分配值。在向量中是否容易实现?
似乎没有简单的方法。因为如果我初始化一个没有大小的向量,那么如果不先通过 resize() 或五个 push_back() 为它分配内存,我就无法访问索引 5。但是调整大小会清除向量中先前存储的值。我可以通过给它一个大小来构造向量,但我不知道向量应该有多大。
那么我怎样才能不必声明固定大小,并且仍然访问向量中的非连续索引?
(我怀疑数组会更容易完成这项任务)。
【问题讨论】:
使用地图不是更好吗? 您为任务选择向量的原因是什么?您是否需要所有元素都存在于连续内存中?您是否与需要数组的 C api 交互? 我认为你说得对,地图更适合这项任务。谢谢。 【参考方案1】:整数键和值之间的 std::map 在这里不是更简单的解决方案吗?向量需要连续分配内存,所以如果你只使用偶尔的索引,你会“浪费”很多内存。
【讨论】:
【参考方案2】:调整大小不会清除矢量。您可以轻松地执行以下操作:
if (v.size() <= n)
v.resize(n+1);
v[n] = 42;
这将保留向量中的所有值并添加足够的默认初始化值,以便可以访问索引n
。
也就是说,如果您不需要所有索引或连续内存,则可以考虑使用不同的数据结构。
【讨论】:
嗯,很有趣。我一直认为 resize() 会清除这些值。我想我在考虑另一种语言? 如果新尺寸小于旧尺寸,那么 resize 会去掉多余的元素。如果新大小更大,则新元素“默认初始化”(对于数字类型,这些值为 0)。【参考方案3】:resize()
不会清除向量中先前存储的值。
见this documentation
我还认为,如果这是您需要做的,那么vector
可能不适合您。您是否考虑过使用map
?
【讨论】:
【参考方案4】:不包含连续值集的数据结构称为稀疏或压缩数据结构。看来这就是你要找的。p>
如果是这种情况,您需要一个稀疏向量。 boost中实现了一个,见link text
稀疏结构通常用于节省内存。根据您的问题描述,您可能实际上并不关心内存使用,而是关心尚不存在的元素(您想要一个自动调整大小的容器)。在这种情况下,一个没有外部依赖的简单解决方案如下:
创建一个模板类,该类包含一个向量并将所有向量方法转发给它。如果索引超出范围,请更改您的 operator[] 以调整向量的大小。
// A vector that resizes on dereference if the index is out of bounds.
template<typename T>
struct resize_vector
typedef typename std::vector<T>::size_type size_type;
// ... Repeat for iterator/value_type typedefs etc
size_type size() const return m_impl.size()
// ... Repeat for all other vector methods you want
value_type& operator[](size_type i)
if (i >= size())
resize(i + 1); // Resize
return m_impl[i];
// You may want a const overload of operator[] that throws
// instead of resizing (or make m_impl mutable, but thats ugly).
private:
std::vector<T> m_impl;
;
如其他答案中所述,调整矢量大小时不会清除元素。相反,当通过调整大小添加新元素时,会调用它们的默认构造函数。因此,您需要知道在使用此类时operator[]
可能会返回一个默认的构造对象引用。因此,<T>
的默认构造函数应为此目的将对象设置为合理的值。例如,如果您需要知道该元素之前是否已被赋值,您可以使用标记值。
使用std::map<size_t, T>
的建议也具有作为解决方案的优点,前提是您不介意额外的内存使用、非连续元素存储和 O(logN) 查找而不是向量的 O(1)。这一切都归结为您是想要稀疏表示还是自动调整大小;希望这个答案涵盖两者。
【讨论】:
以上是关于C++:为向量中的非连续索引赋值?的主要内容,如果未能解决你的问题,请参考以下文章