在 for 循环中调用一个函数来删除向量(或列表)中的元素
call a function, inside a for loop, to remove elements in a vector (or list)
vector<node>::iterator it;
for(it;it!=vector_of_node.end();it++){
if(it->get_name()=="MARIA"){
vector_of_node.erase(it);
}
我希望我的代码目标明确。我想从向量(在本例中为 vector_of_nodes)中消除多个对象(在称为 class 的节点中描述)。
当我 运行 我的代码时,我没有从编译器那里得到任何错误,但是我在 运行ning 时失败了。我确定错误出在我共享的这部分代码上。你能帮帮我吗?
如果根据是否擦除元素在循环内递增迭代器,则可以在迭代时擦除。如果擦除它,erase
方法 returns 向量中的下一个迭代器,如果没有,则自己增加它。此外,您需要将迭代器初始化为 begin
.
vector<node>::iterator it;
for(it=vector_of_node.begin();it!=vector_of_node.end();){
if(it->get_name()=="MARIA")
it = vector_of_node.erase(it);
else
++it;
}
按照您目前的做法,即逐个擦除向量中的元素,必须将擦除后的所有元素移动到向量的前面。这是针对擦除元素的每次迭代完成的(仅当擦除向量的 back 时元素才不会移动)。
作为替代方案,您可能需要考虑 Erase-remove idiom。如果您打算从 std::vector
.
中删除多个元素,则它更适合
// predicate (C++14 for generic lambda)
auto is_maria = [](auto elem) {
return elem.get_name() == "MARIA";
};
auto end = std::remove_if(vector_of_node.begin(), vector_of_node.end(), is_maria);
vector_of_node.erase(end, vector_of_node.end());
我们的想法是将要删除的元素留在向量的后面,然后通过单个 erase()
调用采用范围的相应重载(即,一个迭代器对).
通过一次擦除一个对象来消除向量中的多个对象是非常低效的。每次 erase
调用都会将右侧的所有元素移动一个位置。已经有一个标准库模式可以更好地做到这一点,使用 std::remove
:
std::erase(std::remove_if(vector_of_node.begin(),
vector_of_node.end(),
[](const node& n) { return n->get_name() == "MARIA"; }),
vector_of_node.end());
std::remove_if
的结果是重新排列的向量,所有匹配项都移到了末尾,它 returns 是第一个匹配项的迭代器。然后您调用 std::erase
将它们全部删除。
vector<node>::iterator it;
for(it;it!=vector_of_node.end();it++){
if(it->get_name()=="MARIA"){
vector_of_node.erase(it);
}
我希望我的代码目标明确。我想从向量(在本例中为 vector_of_nodes)中消除多个对象(在称为 class 的节点中描述)。 当我 运行 我的代码时,我没有从编译器那里得到任何错误,但是我在 运行ning 时失败了。我确定错误出在我共享的这部分代码上。你能帮帮我吗?
如果根据是否擦除元素在循环内递增迭代器,则可以在迭代时擦除。如果擦除它,erase
方法 returns 向量中的下一个迭代器,如果没有,则自己增加它。此外,您需要将迭代器初始化为 begin
.
vector<node>::iterator it;
for(it=vector_of_node.begin();it!=vector_of_node.end();){
if(it->get_name()=="MARIA")
it = vector_of_node.erase(it);
else
++it;
}
按照您目前的做法,即逐个擦除向量中的元素,必须将擦除后的所有元素移动到向量的前面。这是针对擦除元素的每次迭代完成的(仅当擦除向量的 back 时元素才不会移动)。
作为替代方案,您可能需要考虑 Erase-remove idiom。如果您打算从 std::vector
.
// predicate (C++14 for generic lambda)
auto is_maria = [](auto elem) {
return elem.get_name() == "MARIA";
};
auto end = std::remove_if(vector_of_node.begin(), vector_of_node.end(), is_maria);
vector_of_node.erase(end, vector_of_node.end());
我们的想法是将要删除的元素留在向量的后面,然后通过单个 erase()
调用采用范围的相应重载(即,一个迭代器对).
通过一次擦除一个对象来消除向量中的多个对象是非常低效的。每次 erase
调用都会将右侧的所有元素移动一个位置。已经有一个标准库模式可以更好地做到这一点,使用 std::remove
:
std::erase(std::remove_if(vector_of_node.begin(),
vector_of_node.end(),
[](const node& n) { return n->get_name() == "MARIA"; }),
vector_of_node.end());
std::remove_if
的结果是重新排列的向量,所有匹配项都移到了末尾,它 returns 是第一个匹配项的迭代器。然后您调用 std::erase
将它们全部删除。