我有一个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(???);
Answers:
要删除单个元素,您可以执行以下操作:
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);
或者,一次删除多个元素:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
operator+
是不是一定适合其他容器类型的迭代定义的,像list<T>::iterator
(你不能做list.begin() + 2
对的std::list
,你必须使用std::advance
该)
std::find_if
std :: vector上的擦除方法已重载,因此调用起来可能更清晰
vec.erase(vec.begin() + index);
当您只想删除单个元素时。
vec.begin()
有效的元素。
vec.erase(0)
行不通,但vec.erase(vec.begin()+0)
(或不带+0)行得通。否则我没有匹配的函数调用,这就是为什么我来这里
vec.erase(0)
实际上可以编译,如果0
碰巧被解释为空指针常量……
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);
}
template <typename T> void remove(std::vector<T>& vec, size_t pos) { vec.erase(vec.begin + pos); }
我并不是说任何一个都更好,只是出于个人利益询问并返回此问题可能获得的最佳结果。
vector<T>::iterator
是随机访问的迭代器,因此您的版本很好,也许更清晰。但是,如果您将容器更改为另一个不支持随机访问迭代器的容器,则Max发布的版本应该可以正常工作
该erase
方法将以两种方式使用:
删除单个元素:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
擦除范围:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
实际上,该erase
功能适用于两个配置文件:
删除单个元素
iterator erase (iterator position);
删除一系列元素
iterator erase (iterator first, iterator last);
由于std :: vec.begin()标记了容器的开始,并且如果我们要删除向量中的ith元素,则可以使用:
vec.erase(vec.begin() + index);
如果仔细看,vec.begin()只是指向向量起始位置的指针,将i的值添加到它的位置会将指针增加到i的位置,因此我们可以通过以下方式访问指向ith元素的指针:
&vec[i]
所以我们可以这样写:
vec.erase(&vec[i]); // To delete the ith element
如果您有一个无序向量,则可以利用它无序的事实,并使用我在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;
}
由于列表顺序无关紧要,因此只需将列表中的最后一个元素复制到要删除的项目上方,然后弹出并删除最后一个项目即可。
iterator + index
实际上会在该索引处返回迭代器位置的假设,这并非对所有可迭代容器都是正确的。通过利用后指针,它也是恒定的复杂度,而不是线性的。
unordered_remove
并且unordered_remove_if
……除非确实如此,但我错过了它,这些天这种情况越来越多了:)
std::remove
重新排序的容器中,使得所有要除去的元素是在端部,无须做手工这样如果使用的是C ++ 17
std::remove
帮助?cppreference声称,即使在C ++ 17中,所有remove
重载都需要谓词,并且没有任何索引。
如果您使用大向量(大小> 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;
}
该代码将vec中无法除以3的每个数字复制到vec2中。然后将其复制到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)
要删除元素,请使用以下方法:
// declaring and assigning array1
std:vector<int> array1 {0,2,3,4};
// erasing the value in the array
array1.erase(array1.begin()+n);
有关更广泛的概述,请访问:http : //www.cplusplus.com/reference/vector/vector/erase/
我建议您阅读此书,因为我相信您正在寻找的东西。https://zh.wikipedia.org/wiki/擦除%E2%80%93remove_idiom
如果您使用例如
vec.erase(vec.begin() + 1, vec.begin() + 3);
您将擦除vector的第n个元素,但是当擦除第二个元素时,vector的所有其他元素将移动并且vector大小将为-1。如果由于矢量size()减小而遍历矢量,则可能会出现问题。如果您有这样的问题,则提供的链接建议使用标准C ++库中的现有算法。和“删除”或“删除_if”。
希望这对您有所帮助
先前的答案假定您始终具有带符号的索引。可悲的是,std::vector
用途size_type
用于索引和difference_type
迭代器算法,因此如果启用了“ -Wconversion”和朋友功能,它们将无法一起使用。这是回答问题的另一种方式,同时能够处理有符号和无符号:
去除:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
v.erase(iter);
}
服用:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
auto val = *iter;
v.erase(iter);
return val;
}
如果要通过在向量中找到元素的值来删除元素,这是另一种方法,您只需要在向量上执行此操作即可。
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
它会从这里删除您的价值。谢谢
最快的方法(用于时间为的编程竞赛,complexity()=常数)
可以在1秒内擦除100M项;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
最易读的方式:
vec.erase(vec.begin() + pos);
vector<int>::iterator
不一定与int *