C ++:std :: vector,为两端保留空间

时间:2017-01-12 11:11:13

标签: c++ arrays vector data-structures

只是一些想法:

我想从大小为n>的std :: vector的开头擦除x个元素。 X。由于向量在内部使用数组,因此可以像将vector.begin()的指针设置为保留的第一个元素的索引一样简单。但相反,擦除会将数组中的所有元素移位到第一个元素实际上从索引0开始,这使得擦除操作所花费的时间远远超过它。

此外,如果有效的'区域'内部数组实际上只是由向量结构的一些开始和结束索引/指针控制,然后还有在第一个元素前面保留空间的选项。例如,向量被初始化并且在结尾处保留20个空格并且在开始处保留10个空格。在内部,然后创建一个空间数组30(或32),其中起始索引/指针指向内部数组的第11个值,允许在“向量”的前面包含新元素。以恒定的速度。

嗯,我的观点是,我认为这样的数据结构会有所帮助,至少对我而言。我很确定有人已经想到这个并且已经实现了它。所以我想问一下:我所描述的数据结构是如何形成的?如果存在,我很乐意使用它。我认为这不是一个双链表,因为在那里,每个元素都是一个包含元素值和附加指针的结构(据我所知)。

编辑:是的,这样的结构可能会使用比必要更多的内存,特别是从开头删除一些元素时,因为那时,内部数组仍然具有初始大小。但是,对于大多数问题,记忆不再是一个大问题,并且可能存在(时间昂贵的)记忆优化'创建一个新的,更小的数组,复制所有旧值并删除旧的内部数组以使用尽可能小的大小的操作。

1 个答案:

答案 0 :(得分:1)

扩展@Kerrek SB的评论,boost::circular_buffer<>我认为你需要什么,例如:

#include <iostream>
#include <boost/circular_buffer.hpp>

int main()
{
  boost::circular_buffer<int> cb(3);

  cb.push_back(1);
  cb.push_back(2);
  cb.push_back(3);

  for( auto i : cb) {
      std::cout << i << std::endl;
  }

  // Increase to hold two more items
  cb.set_capacity(5);
  cb.push_back(4);
  cb.push_back(5);

  for( auto i : cb) {
      std::cout << i << std::endl;
  }

  // Increase to hold two more items
  cb.rset_capacity(7);
  cb.push_front(0);
  cb.push_front(-1);

  for( auto i : cb) {
      std::cout << i << std::endl;
  }  
}
TBH - 我没有看过实现,因此无法评论它是否会移动数据(我非常惊讶)。但是如果你下拉源代码,请快速查看以确定性能是否正常关注......

编辑:快速查看代码显示push_xxx操作确实没有移动数据,但xxx_capacity操作确实会导致移动/复制 - 为了避免这种情况,请确保环具有一开始就有足够的容量,它可以按你的意愿工作......