dau*_*man 464 c++ stl vector erase
我有一个std :: vector <int>,我想删除第n个元素.我怎么做?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
Run Code Online (Sandbox Code Playgroud)
mmm*_*mmm 645
要删除单个元素,您可以执行以下操作:
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);
Run Code Online (Sandbox Code Playgroud)
或者,一次删除多个元素:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
Run Code Online (Sandbox Code Playgroud)
Cod*_*ddy 197
std :: vector上的erase方法被重载,因此调用它可能更清晰
vec.erase(vec.begin() + index);
Run Code Online (Sandbox Code Playgroud)
当你只想删除一个元素时.
Max*_*Max 52
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
std::vector<T>::iterator it = vec.begin();
std::advance(it, pos);
vec.erase(it);
}
Run Code Online (Sandbox Code Playgroud)
Esw*_*ndi 13
该erase方法将以两种方式使用:
擦除单个元素:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
Run Code Online (Sandbox Code Playgroud)擦除元素范围:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
Run Code Online (Sandbox Code Playgroud)小智 9
擦除带有索引的元素:
vec.erase(vec.begin() + index);
Run Code Online (Sandbox Code Playgroud)
擦除具有值的元素:
vec.erase(find(vec.begin(),vec.end(),value));
Run Code Online (Sandbox Code Playgroud)
实际上,该erase功能适用于两个配置文件:
删除单个元素
iterator erase (iterator position);
Run Code Online (Sandbox Code Playgroud)删除一系列元素
iterator erase (iterator first, iterator last);
Run Code Online (Sandbox Code Playgroud)由于std :: vec.begin()标记容器的开头,如果我们想删除向量中的第i个元素,我们可以使用:
vec.erase(vec.begin() + index);
Run Code Online (Sandbox Code Playgroud)
如果仔细观察,vec.begin()只是指向我们向量的起始位置的指针,并且将i的值添加到它会将指针递增到i位置,所以我们可以通过以下方式访问指向第i个元素的指针:
&vec[i]
Run Code Online (Sandbox Code Playgroud)
所以我们可以写:
vec.erase(&vec[i]); // To delete the ith element
Run Code Online (Sandbox Code Playgroud)
对某些人来说似乎很明显,但要详细说明上述答案:
如果您在整个向量的循环中std::vector使用删除元素erase,您应该以相反的顺序处理您的向量,也就是说使用
for (int i = v.size() - 1; i >= 0; i--)
而不是(经典的)
for (int i = 0; i < v.size(); i++)
原因是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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
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 # # # # #
Run Code Online (Sandbox Code Playgroud)
请注意,在索引增加的第二个版本中,偶数不会显示,因为它们被跳过,因为 i++
小智 7
如果你有一个无序的向量,你可以利用它无序的事实,并使用我在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;
}
Run Code Online (Sandbox Code Playgroud)
由于列表顺序无关紧要,只需取出列表中的最后一个元素并将其复制到要删除的项目的顶部,然后弹出并删除最后一项.
小智 6
如果您使用大向量(大小 > 100,000)并想要删除大量元素,我建议您执行以下操作:
int main(int argc, char** argv) {
vector <int> vec;
vector <int> vec2;
for (int i = 0; i < 20000000; i++){
vec.push_back(i);}
for (int i = 0; i < vec.size(); i++)
{
if(vec.at(i) %3 != 0)
vec2.push_back(i);
}
vec = vec2;
cout << vec.size() << endl;
}
Run Code Online (Sandbox Code Playgroud)
该代码获取 vec 中不能被 3 整除的每个数字并将其复制到 vec2。然后它在 vec 中复制 vec2。它非常快。要处理 20,000,000 个元素,这个算法只需要 0.8 秒!
我用擦除方法做了同样的事情,它需要很多很多时间:
Erase-Version (10k elements) : 0.04 sec
Erase-Version (100k elements) : 0.6 sec
Erase-Version (1000k elements): 56 sec
Erase-Version (10000k elements): ...still calculating (>30 min)
Run Code Online (Sandbox Code Playgroud)
小智 6
我建议您阅读有关擦除\xe2\x80\x93remove 惯用语的内容。
例如:
vec.erase(vec.begin() + 1, vec.begin() + 3);\nRun Code Online (Sandbox Code Playgroud)\n这样,您将擦除 的n第一个元素vec,但在擦除第二个元素之前,的所有其他元素vec将被移位,并且向量大小将减少 1。这可能是一个问题,因为您可能会vec在其size()为时循环减少。
如果您遇到这样的问题,提供的链接建议使用remove和remove_if。
| 归档时间: |
|
| 查看次数: |
694698 次 |
| 最近记录: |