从std::vector中的特定索引中删除
Delete from specific indexes in a std::vector
假设我有一个包含5个元素的std::向量,我需要从索引1和3中删除元素,这是最快的方法。在标准库中是否有任何辅助方法可以为我做到这一点?
您可以使用erase
函数。对于这个特定的案例,你提到了这样的东西:
myvector.erase (myvector.begin()+3);
myvector.erase (myvector.begin()+1);
会成功的。您必须为erase
函数提供一个迭代器,我建议您阅读文档以了解其用法。以上内容应该适用于您的情况。请注意,每次擦除调用都会在移除位置后更改其余元素的索引,因为内部数组元素将相对于移除的项目进行调整。
作为对您的评论的回应,您一次只能擦除一个元素,除非它们是连续索引,在这种情况下,您可以使用基于范围的擦除版本,使用开始和结束迭代器。例如,如果您想擦除索引1,2和3,请使用
myvector.erase (myvector.begin()+1,myvector.begin()+4);
正如我已经提到的,在你删除的项目之后,项目的索引将相应地降低。这是不可避免的,因为数组中不能有"间隙"。
这应该是一个使用std::move
并且每个元素最多只移动一次的相当有效的实现。它要求对to_remove
中要删除的索引进行排序。
template<typename T>
void remove_index(std::vector<T>& vector, const std::vector<int>& to_remove)
{
auto vector_base = vector.begin();
std::vector<T>::size_type down_by = 0;
for (auto iter = to_remove.cbegin();
iter < to_remove.cend();
iter++, down_by++)
{
std::vector<T>::size_type next = (iter + 1 == to_remove.cend()
? vector.size()
: *(iter + 1));
std::move(vector_base + *iter + 1,
vector_base + next,
vector_base + *iter - down_by);
}
vector.resize(vector.size() - to_remove.size());
}
// Usage:
//
// std::vector<std::string> values = { "0", "1", "2", "3", "4", "5"};
// remove_index(values, { 1, 3 });
这比逐个删除它们快得多(尽管在某些情况下仍然可以加快速度):
template<class It>
struct remover
{
size_t *i;
It *begin;
It const *end;
explicit remover(size_t &i, It &begin, It const &end) : i(&i), begin(&begin), end(&end) { }
template<class T>
bool operator()(T const &)
{
size_t &i = *this->i;
It &begin = *this->begin;
It const &end = *this->end;
while (begin != end && *begin < i) /* only necessary in case there are duplicate indices */
{ ++begin; }
bool const b = begin != end && *begin == i;
if (b) { ++begin; }
++i;
return b;
}
};
template<class Container, class IndexIt>
IndexIt remove_indices(Container &items, IndexIt indices_begin, IndexIt const &indices_end)
{
size_t i = 0;
std::sort(indices_begin, indices_end);
items.erase(std::remove_if(items.begin(), items.end(), remover<IndexIt>(i, indices_begin, indices_end)), items.end());
return indices_begin;
}
int main()
{
std::vector<int> items(100);
std::vector<size_t> indices;
indices.push_back(5);
indices.push_back(1);
remove_indices(items, indices.begin(), indices.end());
}
如果你想擦除矢量中的一些任意元素,你可以用以下方法
for ( int i : { 3, 1 } ) v.erase( std::next( v.begin(), i ) );
请考虑初始值设定项列表中的项应按降序排列。
相关文章:
- 删除最小堆中的第 i 个索引
- 使用对象的索引从矢量中删除对象
- 如何通过索引中删除向量中的2个元素的每个倍数
- 从<string>向量<int>中定义的索引处的向量中删除字符串
- <T> 在使用运算符+ 连接两个向量之前从类型向量中删除索引
- 如何删除给定索引之间的所有元素
- 通过索引从向量中删除对象
- 双链表删除节点与索引C++
- 如何在删除一行后重新索引或修复rowid sqlite
- std::vector 删除重复项,然后删除另一个向量中的相同索引
- C++-从单链循环列表中的任何索引中删除一个节点
- 如何从结构数组中删除一个数据行?(带索引)
- 从std::vector中的特定索引中删除
- C++ 索引数组打印和删除字符串名称 数组打印
- 从给定索引处的向量中删除对象
- 删除字符*[] 中的第一个索引
- 删除 2 个给定索引之间的元素的最佳算法
- 通过索引删除一组元素
- 向量的向量.根据内部向量的特定索引删除重复项
- 根据索引删除向量元素