连续删除矢量元素
Consecutive removing of vector elements
我需要从向量 a 和 b 中删除元素,如果这些元素相等。据我了解,当我删除一个元素时,其他元素也会移动。因此,a[1] 变为 a[0]、a[2] -- a[1] 等等。但是我的代码不能正常工作:
#include <iostream>
#include <vector>
using namespace std;
bool remove(vector<int>& a, vector<int>& b){
for (size_t i = 0; i < a.size(); ++i )
{
while ( true )
{
std::vector<int>::iterator it;
it = std::find(b.begin(), b.end(), a[i]);
if ( it != b.end() )
{
i = 0; //because of moving elements
b.erase(b.begin()+i);
a.erase(a.begin()+i);
break;
}
}
}
return true;
}
int main(){
vector<int> a;
vector<int> b;
a.push_back(1);
a.push_back(2);
a.push_back(3);
b.push_back(1);
b.push_back(2);
b.push_back(3);
remove(a,b);
return 0;
}
问题是 - 最后一个相等的元素保留下来,所以我无法删除它们。考虑到不相等的元素可能位于向量的中间,我该如何解决这个问题:a = 1, 2, 3; b = 1, 3, 3 -- 不应该删除向量 a 中的 2 和向量 b 中的 3?
As I understand, when I remove an element, other elements move.
部分正确。如果删除一个元素,after 元素将被向下推以填充孔。如果删除第 5 个元素,则原为第 6 个元素的元素现在变为第 5 个。但是第 4 个元素仍然是第 4 个。这当然只有在你擦除 之后才是正确的。所以你的代码是:
i = // the element from a
it = // the iterator pointing to an element from b
i = 0;
b.erase(b.begin()+i); // erase the 1st element from b
a.erase(a.begin()+i); // erase the 1st element from a
你做所有这些工作来找到一对相等的元素,然后立即丢弃它——擦除两个向量的前面的元素。这就是为什么它不起作用。您想要删除找到的元素:
b.erase(it);
a.erase(a.begin() + i); // no i = 0
请注意,如果您想删除在另一个数组中具有匹配项的每个元素,则此修复不会削减它 - 如果您在 a
中有两个 1
,但只有一个在 b
中,您永远不会删除第二个。为此,我们需要利用 Erase-remove idiom:
for (std::vector<int>::iterator itA = a.begin(); itA != a.end(); /* nothing */)
{
std::vector<int>::iterator itB = std::find(b.begin(), b.end(), *itA);
if (itB == b.end()) {
// done with this element, move on
++itA;
}
else {
// erase EVERYTHING
b.erase(std::remove(itB, b.end(), *itA), b.end());
itA = a.erase(std::remove(itA, a.end(), *itA), a.end());
}
}
我需要从向量 a 和 b 中删除元素,如果这些元素相等。据我了解,当我删除一个元素时,其他元素也会移动。因此,a[1] 变为 a[0]、a[2] -- a[1] 等等。但是我的代码不能正常工作:
#include <iostream>
#include <vector>
using namespace std;
bool remove(vector<int>& a, vector<int>& b){
for (size_t i = 0; i < a.size(); ++i )
{
while ( true )
{
std::vector<int>::iterator it;
it = std::find(b.begin(), b.end(), a[i]);
if ( it != b.end() )
{
i = 0; //because of moving elements
b.erase(b.begin()+i);
a.erase(a.begin()+i);
break;
}
}
}
return true;
}
int main(){
vector<int> a;
vector<int> b;
a.push_back(1);
a.push_back(2);
a.push_back(3);
b.push_back(1);
b.push_back(2);
b.push_back(3);
remove(a,b);
return 0;
}
问题是 - 最后一个相等的元素保留下来,所以我无法删除它们。考虑到不相等的元素可能位于向量的中间,我该如何解决这个问题:a = 1, 2, 3; b = 1, 3, 3 -- 不应该删除向量 a 中的 2 和向量 b 中的 3?
As I understand, when I remove an element, other elements move.
部分正确。如果删除一个元素,after 元素将被向下推以填充孔。如果删除第 5 个元素,则原为第 6 个元素的元素现在变为第 5 个。但是第 4 个元素仍然是第 4 个。这当然只有在你擦除 之后才是正确的。所以你的代码是:
i = // the element from a
it = // the iterator pointing to an element from b
i = 0;
b.erase(b.begin()+i); // erase the 1st element from b
a.erase(a.begin()+i); // erase the 1st element from a
你做所有这些工作来找到一对相等的元素,然后立即丢弃它——擦除两个向量的前面的元素。这就是为什么它不起作用。您想要删除找到的元素:
b.erase(it);
a.erase(a.begin() + i); // no i = 0
请注意,如果您想删除在另一个数组中具有匹配项的每个元素,则此修复不会削减它 - 如果您在 a
中有两个 1
,但只有一个在 b
中,您永远不会删除第二个。为此,我们需要利用 Erase-remove idiom:
for (std::vector<int>::iterator itA = a.begin(); itA != a.end(); /* nothing */)
{
std::vector<int>::iterator itB = std::find(b.begin(), b.end(), *itA);
if (itB == b.end()) {
// done with this element, move on
++itA;
}
else {
// erase EVERYTHING
b.erase(std::remove(itB, b.end(), *itA), b.end());
itA = a.erase(std::remove(itA, a.end(), *itA), a.end());
}
}