从给定索引上的向量中移除元素,顺序无关紧要
Remove elements from vector on given indexes, order does not matter
我所拥有的是元素的向量,我不在乎它们的顺序。Than I具有要从向量中移除的元素的N
索引(每个索引寻址向量中的唯一位置)。我希望尽快移除。
我能想到的最好的办法是将索引存储在集合中(排序索引):
std::set<unsigned int> idxs;
for (int i=0; i<N; ++i)
idxs.insert(some_index);
然后以相反的顺序迭代集合,并用向量的最后一个元素替换要删除的索引。
std::set<unsigned int>::reverse_iterator rit;
for (rit = idxs.rbegin(); rit != idxs.rend(); ++rit) {
vec[*rit].swap(vec[vec.size() - 1]);
vec.resize(vec.size() - 1);
}
然而,我在想是否有更有效的方法可以做到这一点,因为集合的使用对我来说有点过头了,我希望完全避免排序。
第1版:让我们假设我使用向量,然后对其进行排序。
std::vector<unsigned int> idxs;
for (int i=0; i<N; ++i)
idxs.push_back(some_index);
std::sort(idxs.begin(), idxs.end());
我可以再推一点吗?
第2版:我应该提到,向量将有多达10个元素。然而,我的程序中的删除经常发生(数十万次)。
set
是一个不错的选择。我想使用另一个分配器(例如arena)会产生最大的影响。为什么不使用元素的集合而不是向量来开始呢?
我看到以下相关变化:
-
创建一个新的矢量并复制保留的元素,然后交换回,而不是移除
这可以保持索引的稳定(不像删除那样需要对索引进行排序或更新)。 -
使用与数据长度相同的布尔向量,而不是索引向量。给定"最大10"的长度,一个比特掩码似乎就足够了
所以,大致来说:
struct Index
{
DWORD removeMask = 0; // or use bit vector for larger N
void TagForRemove(int idx) { removeMask |= (1<<idx); }
boll DoRemove(int idx) const { return (removeMask & (1<<idx)) != 0; }
}
// create new vector, or remove, as you like
void ApplyRemoveIndex(vector<T> & v, Index remove)
{
vector<T> copy;
copy.reserve(v.size());
for (i=0..v.size())
if (!remove.DoRemove(i))
copy.push_back(v[i]);
copy.swap(v);
}
您可以使用swap
/pop_back
删除给定索引处的项,并使用哈希表跟踪移动的索引。它是线性空间&清除次数中的时间。
std::vector<T> vec = ...;
std::vector<unsigned int> idxs;
std::unordered_map<unsigned int, unsigned int> map;
for(auto index : idxs) {
unsigned int trueIndex = index;
while (trueIndex >= vec.size()) {
trueIndex = map[trueIndex];
}
// element at index 'vec.size()-1' is being moved to index 'index'
map[vec.size()-1] = index;
swap(vec[trueIndex], vec[vec.size()-1]);
vec.pop_back();
}
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 数到第n个楼梯的路(顺序无关紧要)
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 从给定索引上的向量中移除元素,顺序无关紧要