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[] 可能会返回一个默认的构造对象引用。因此,&lt;T&gt; 的默认构造函数应为此目的将对象设置为合理的值。例如,如果您需要知道该元素之前是否已被赋值,您可以使用标记值。

使用std::map&lt;size_t, T&gt; 的建议也具有作为解决方案的优点,前提是您不介意额外的内存使用、非连续元素存储和 O(logN) 查找而不是向量的 O(1)。这一切都归结为您是想要稀疏表示还是自动调整大小;希望这个答案涵盖两者。

【讨论】:

以上是关于C++:为向量中的非连续索引赋值?的主要内容,如果未能解决你的问题,请参考以下文章

为向量索引赋值

将单行向量(数组)赋值转换为经典数组,C++ 转换为 C

为指针向量赋值

带有浮点索引的 C++ 数组/向量

优化向量赋值 c++

如何使用 R 在向量中找到第二个非连续出现的值的索引?