我在从集合中删除元素时遇到了麻烦。我从以下位置得到 BUILD FAILED
:
n2Ar.erase(it);
n3Ar.erase(it);
其中 it
是从 find()
函数接收的指针:例如it = n2Ar.find(*i);
整个程序 list :
#include <stdio.h>
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
#define TESTING_FILE_IN
//#define TESTING_FILE_OUT
//#define DEBUG
//#define SHOW_TIMING
int outputSet(int i) {
cout << i << endl;
}
/*
*
*/
int main() {
int n1, n2, n3;
set<int> list, n1Ar, n2Ar, n3Ar;
set<int>::iterator it;
scanf("%d", &n1);
scanf("%d", &n2);
scanf("%d", &n3);
int val = 0;
// Getting lists of voters
for (unsigned i = 0; i < n1; i++) {
cin >> val;
n1Ar.insert(val);
}
for (unsigned i = 0; i < n2; i++) {
cin >> val;
n2Ar.insert(val);
}
for (unsigned i = 0; i < n3; i++) {
cin >> val;
n3Ar.insert(val);
}
// Processing lists
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); ++i) {
it = n2Ar.find(*i);
if (it != n2Ar.end()) {
list.insert(*i);
n1Ar.erase(i);
n2Ar.erase(it);
} else {
it = n3Ar.find(*i);
if (it != n3Ar.end()) {
list.insert(*i);
n1Ar.erase(i);
n3Ar.erase(it);
}
}
}
// Outputting the final list
cout << list.size() << endl;
for_each(list.begin(), list.end(), outputSet);
return 0;
}
我希望你能帮助我理解我在这里做错了什么。我只是从 C++ 开始。
最佳答案
您的代码中有两个问题。
首先,您需要在下面的函数中返回一个值,或者简单地让它返回 void。
// you should return a value here or make it return void
int outputSet(int i)
{
cout << i << endl;
}
其次,一旦您移除当前迭代器,for 循环的后续迭代中的迭代器将失效。一旦一个元素被移除,它的迭代器i也将失效,以致于后面基于++i的迭代器;
你会得到运行时错误,因为迭代器 i 现在指向你需要以某种方式“重置”它。
MSVC 实现
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); ++i) {
it = n2Ar.find(*i);
if (it != n2Ar.end()) {
list.insert(*i);
// the following iterators become invalidated after the
// current one is removed. You need reset it like
// i = n1Ar.erase(i);
n1Ar.erase(i);
n2Ar.erase(it);
} else {
it = n3Ar.find(*i);
if (it != n3Ar.end()) {
list.insert(*i);
// the following iterators become invalidated after the
// current one is removed. You need reset it like
// i = n1Ar.erase(i);
n1Ar.erase(i);
n3Ar.erase(it);
}
}
}
编辑:请注意,从 set::erase() 返回新的迭代器不是标准方法。这主要是为了性能。
更便携的解决方案
基本思想是在删除当前迭代器之前正确设置下一个迭代器。
set<int>::iterator i = n1Ar.begin();
while (i != n1Ar.end())
{
it = n2Ar.find(*i);
if (it != n2Ar.end())
{
// the trick is to use "i++" where i is incremented by one while "old" i
// is removed.
list.insert(*i);
n1Ar.erase(i++);
n2Ar.erase(it);
}
else
{
it = n3Ar.find(*i);
if (it != n3Ar.end())
{
list.insert(*i);
n1Ar.erase(i++);
n3Ar.erase(it);
}
else
{
++i;
}
}
}
关于c++ - 从集合中删除元素的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6967134/