我有一个std::vector<int>,我想删除第n个元素。我怎么做呢?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
我有一个std::vector<int>,我想删除第n个元素。我怎么做呢?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
当前回答
最快的方法(对于时间复杂度()=常量的编程竞赛)
可在1秒内擦除100M项目;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
最易读的方式: Vec.erase (vec.begin() + pos);
其他回答
如果你有一个无序向量,你可以利用它是无序的这一事实,并使用我在CPPCON上从Dan Higgins那里看到的东西
template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
if ( inIndex < inContainer.size() )
{
if ( inIndex != inContainer.size() - 1 )
inContainer[inIndex] = inContainer.back();
inContainer.pop_back();
return true;
}
return false;
}
由于列表顺序无关紧要,只需取列表中的最后一个元素并将其复制到您想要删除的项之上,然后弹出并删除最后一项。
最快的方法(对于时间复杂度()=常量的编程竞赛)
可在1秒内擦除100M项目;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
最易读的方式: Vec.erase (vec.begin() + pos);
你需要使用标准模板库的std::vector::erase函数。
示例:从vector中删除一个元素(使用index)
// Deleting the eleventh element from vector vec
vec.erase( vec.begin() + 10 );
以上代码的解释
std::向量< T,分配器>::消除用法:
iterator erase (iterator position); // until C++11
iterator erase( const_iterator pos ); // since C++11 and until C++20
constexpr iterator erase( const_iterator pos ); // since C++20
这里有一个参数position,它是指向要从vector中移除的单个元素的迭代器。 成员类型iterator和const_iterator是指向元素的随机访问迭代器类型。
它是如何工作的
擦除函数做以下工作:
它从向量中删除单个元素(position)或一组元素([first, last))。 它通过删除被销毁的元素的数量来减小容器的大小。
注意:迭代器pos必须有效且可解引用。因此end()迭代器(有效,但不可解引用)不能用作pos的值。
返回值和复杂度
返回值是一个迭代器,指向被函数调用擦除的最后一个元素后面的元素的新位置。这是擦除序列中最后一个元素的操作的容器结束。
成员类型迭代器是指向元素的随机访问迭代器类型。
在这里,时间复杂度与删除的元素数量(销毁)加上最后一个元素删除后的元素数量(移动)成线性关系。
对于一些人来说,这似乎是显而易见的,但要详细说明以上的答案:
如果你在整个向量上使用erase循环删除std::vector元素,你应该以相反的顺序处理你的向量,也就是说使用
For (int I = v.size() - 1;I >= 0;我——)
而不是(古典的)
For (int I = 0;I < v.size();我+ +)
原因是索引会受到erase的影响,所以如果你删除了第4个元素,那么之前的第5个元素就变成了新的第4个元素,如果你在执行i++,它就不会被循环处理。
下面是一个简单的例子来说明这一点,我想删除一个int向量的所有odds元素;
#include <iostream>
#include <vector>
using namespace std;
void printVector(const vector<int> &v)
{
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
int main()
{
vector<int> v1, v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i);
}
// print v1
cout << "v1: " << endl;
printVector(v1);
cout << endl;
// print v2
cout << "v2: " << endl;
printVector(v2);
// Erase all odd elements
cout << "--- Erase odd elements ---" << endl;
// loop with decreasing indices
cout << "Process v2 with decreasing indices: " << endl;
for (int i = v2.size() - 1; i >= 0; i--)
{
if (v2[i] % 2 != 0)
{
cout << "# ";
v2.erase(v2.begin() + i);
}
else
{
cout << v2[i] << " ";
}
}
cout << endl;
cout << endl;
// loop with increasing indices
cout << "Process v1 with increasing indices: " << endl;
for (int i = 0; i < v1.size(); i++)
{
if (v1[i] % 2 != 0)
{
cout << "# ";
v1.erase(v1.begin() + i);
}
else
{
cout << v1[i] << " ";
}
}
return 0;
}
输出:
v1:
0 1 2 3 4 5 6 7 8 9
v2:
0 1 2 3 4 5 6 7 8 9
--- Erase odd elements ---
Process v2 with decreasing indices:
# 8 # 6 # 4 # 2 # 0
Process v1 with increasing indices:
0 # # # # #
注意,在第二个增加索引的版本中,偶数不会显示出来,因为i++跳过了它们
还要注意的是,以相反的顺序处理向量,你不能对索引使用unsigned类型(for (uint8_t i = v.size() -1;... 不会工作)。这是因为当i = 0时,i—将溢出,并等于255 uint8_t为例(因此循环不会停止,因为i仍然是>= 0,可能超出了向量的边界)。
这里还有一种方法,如果你想删除一个元素,通过在vector中找到它的值,你只需要在vector上做这个。
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
它会把你的价值从这里抹去。 谢谢