【发布时间】:2017-11-04 18:15:43
【问题描述】:
我正在处理需要随机选择并有效删除的元素向量,直到满足任何一个条件,或者直到所有元素都被选中。但是,直到代码执行的某个后期阶段,它们才会真正被删除,因此我需要维护一个有效、可用元素的列表。我可以从第二个向量中删除元素,或者我可以每次都重新创建它。请在下面查看我的代码的最小版本,该示例显示了在 while 循环中每次创建向量的位置:
Random mRandom; // Pseudo-random number generator
std::vector< Element* > mElements;
for( unsigned index = 0; index < ARBITRARY_VALUE; index++ )
mElements.push_back( new Element( ) );
std::vector< bool > removedElements;
bool condition = true;
while( condition == true ) {
std::vector< unsigned > availableIndices;
for( unsigned index = 0; index < mElements.size( ); index++ ) {
if( removedElements[ index ] == false )
availableIndices.push_back( index );
}
if( availableIndices.size( ) > 0 ) {
unsigned maximum = availableIndices.size( ) - 1;
unsigned randomIndex = mRandom.GetUniformInt( maximum ); // Zero to max
removedElements[ availableIndices[ randomIndex ] ] = true;
Element* element = mElements[ availableIndices[ randomIndex ] ];
condition = element->DoStuff( ); // May change condition and exit while
} else
break;
}
很明显,擦除向量中间的元素需要底层系统遍历剩余元素并将它们“移动”到新的有效位置。显然,如果擦除的元素接近向量的末尾,这意味着更少的迭代。
我已经阅读了一些关于擦除矢量元素相关成本的帖子,但我没有看到任何直接解决我的问题的内容。擦除后“移动”元素的过程是否会引入开销,通过创建一个指向有效元素的新向量,每次迭代所有元素时都会变得更便宜?就像我上面的代码示例一样。
干杯,菲尔
【问题讨论】:
-
看起来您希望
std::stable_partition对最终将被删除的元素进行分区。 -
mElements中的顺序重要吗?如果没有,那么您可以简单地使用std::swap(mElements[randomIndex], mElements[--cur_size]);“删除”一个元素(其中cur_size在循环之前用mElements.size()初始化)。换句话说,将“已移除”的元素移动到最后,在进一步处理中忽略它们。如果需要,您可以在最后一次erase它们。
标签: c++ performance vector processing-efficiency cpu-speed