C++:从只能通过迭代器访问的数据类型中高效地提取元素子集

C++: Efficiently extracting a subset of elements from a datatype that only has access via an iterator

本文关键字:高效 数据类型 提取 子集 元素 访问 迭代器 C++      更新时间:2023-10-16

我有另一个人用户定义的数据结构(用于处理网格)。对底层元素的唯一公共访问是通过迭代器(不可能直接访问"元素"x)。

我还有一个元素索引列表,存储为我想要提取的std::vector,其中我将迭代器访问的第一个元素定义为index=1、index=2等。实际上,我想要基于索引提取元素的子集。

我将多次这样做(我采样的网格将不断变化,我想保持对相同索引的采样),因此我需要尽可能有效的方法。

目前,我真的想不出比将所有元素添加到std::向量中,然后循环元素索引列表并选择所有所需元素更有效的方法了。理想情况下,由于时间和存储的原因,这似乎不是一个很好的方法

任何建议都将不胜感激。

如果向量是预先排序的,那么您只需要迭代一次。不过,您需要自己在第三方迭代器中维护计数。请尝试以下代码的变体(注意:此代码缺少错误和边界检查。)

iterator elementIt;
int elementPos = 0;
vector<int> extractElements;
for (vector<int>::iterator extractIt = extractElements.begin(); extractIt != extractElements.end(); ++extractIt)
{
  while (elementPos < *extractIt)
  {
    ++elementIt;
    ++elementPos;
  }
  doSomething(elementIt);
}

假设您可以通过现有iterator对象的偏移量(即通过begin() getter方法)访问暴露的iterator对象,那么您可能能够执行以下

DataStructure_type::iterator iter = dataStructureVar.begin();
elementValue = *(iter + idx);

其中DataStructure_type是可迭代数据结构的类型,idx是所需元素的索引。然后,从数据结构中提取元素的子集变得很简单:

DataStructure_type::iterator subsetStartIter = dataStructureVar.begin() + subsetStartIdx;
DataStructure_type::iterator subsetEndIter = dataStructureVar.begin() + subsetEndIdx;
std::vector<Element_type> subsetCollection(subsetStartIter, subsetEndIter);

但是,如果直接对代码中的原始子集iterator对象进行操作,而不是将它们复制到中间容器,则可能会更高效——这将消除将子集复制到std::vector<>的需要。。。

请注意,这个答案对DataStructure_type中公开的iterator对象的实现进行了某些假设,并且没有考虑边界检查。