C++ 从集合中删除元素时出现问题
我在从集合中删除元素时遇到问题。我从以下位置获取C++ 从集合中删除元素时出现问题,c++,set,erase,C++,Set,Erase,我在从集合中删除元素时遇到问题。我从以下位置获取生成失败的: n2Ar.erase(it); n3Ar.erase(it); 其中it是从find()函数接收的指针:例如it=n2Ar.find(*i) 该计划的全部清单: #include <stdio.h> #include <iostream> #include <vector> #include <set> #include <algorithm> using namespa
生成失败的:
n2Ar.erase(it);
n3Ar.erase(it);
其中it
是从find()
函数接收的指针:例如it=n2Ar.find(*i)代码>
该计划的全部清单:
#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;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#在中定义测试文件
//#定义测试文件
//#定义调试
//#定义显示时间
int输出集(int i){
库特瓦尔;
n1Ar.插入(val);
}
for(无符号i=0;i>val;
n2Ar.插入值(val);
}
for(无符号i=0;i>val;
n3Ar.插入件(val);
}
//处理列表
for(set::iterator i=n1Ar.begin();i!=n1Ar.end();++i){
它=n2Ar.find(*i);
如果(it!=n2Ar.end()){
清单.插入(*i);
n1Ar.擦除(i);
n2Ar.擦除(它);
}否则{
它=n3Ar.find(*i);
如果(it!=n3Ar.end()){
清单.插入(*i);
n1Ar.擦除(i);
n3Ar.擦除(它);
}
}
}
//输出最终列表
cout您的代码中有两个问题
首先,您需要在下面的函数中返回一个值,或者简单地使其返回void
// you should return a value here or make it return void
int outputSet(int i)
{
cout << i << endl;
}
//您应该在此处返回一个值,或者将其设为return void
int输出集(int i)
{
库特
STD::SET::擦除函数使迭代器i无效并导致问题。请考虑以下更改:
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); ++i) {
it = n2Ar.find(*i);
if (it != n2Ar.end()) {
list.insert(*i);
i = n1Ar.erase(i);
if(i == n1Ar.cend())
break;
n2Ar.erase(it);
} else {
for(set::iterator i=n1Ar.begin();i!=n1Ar.end();++i){
它=n2Ar.find(*i);
如果(it!=n2Ar.end()){
清单.插入(*i);
i=n1Ar.擦除(i);
如果(i==n1Ar.cend())
打破
n2Ar.擦除(它);
}否则{
if(i==n1Ar.cend())中断;
检查有助于确保无效迭代器不会破坏循环
擦除方法使迭代器i无效
方法不返回迭代器
编辑:您可以使用以下代码:
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); )
if ( n2Ar.erase(*i) || n3Ar.erase(*i) ) {
list.insert(*i);
n1Ar.erase(i++);
} else i++;
for(set::iterator i=n1Ar.begin();i!=n1Ar.end();)
if(n2Ar.擦除(*i)| n3Ar.擦除(*i)){
清单.插入(*i);
n1Ar.擦除(i++);
}否则i++;
这个问题也可以用标准算法解决。但这个解决方案似乎效率较低:
set<int> tmp;
std::set_union( n2Ar.begin(), n2Ar.end(),
n3Ar.begin(), n3Ar.end(), std::inserter(tmp,tmp.begin()) );
std::set_intersection( n1Ar.begin(), n1Ar.end(),
tmp.begin(), tmp.end(), std::inserter(list,list.begin()) );
设置tmp;
std::set_union(n2Ar.begin(),n2Ar.end(),
n3Ar.begin(),n3Ar.end(),std::inserter(tmp,tmp.begin());
标准::设置交叉点(n1Ar.begin(),n1Ar.end(),
tmp.begin(),tmp.end(),std::inserter(list,list.begin());
最后,我建议对输出使用stl(您必须包括迭代器库):
std::copy(list.begin()、list.end()、std::ostream_迭代器(std::cout,“\n”);
请向我们显示准确的错误消息。返回值看起来像是问题所在,但擦除后,std::set
迭代器不会失效,std::set::erase
通常不会返回迭代器(但它作为Visual Studio扩展)。它在C++0x中确实返回迭代器。一些标准容器在C++03中的接口中确实返回这样的迭代器。感谢您的回复!我尝试使用I=n1Ar.erase(I);
但我找不到此编译器错误的解决方法:错误:I=n1Ar.std::set::erase中的'operator='不匹配[使用_Key=int、_Compare=std::less、_Alloc=std::allocator](i)
(我使用的是Netbeans 7.0.1)@DeadMG,它是否包括像set这样的关联容器?@Hollgam,如果您不使用MSVC,请尝试第二种解决方案。set::erase()可能会在您的实现中返回void。您的意思是.end()?
。如果是,我会得到与Eric的解决方案相同的编译器错误。@Hollgam,cend()是c++0x中的新东西。但它与您的问题无关。出现编译错误的原因是“I=n1Ar.erase(I)”不符合旧标准。这实际上取决于您使用的编译器。
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); ++i) {
it = n2Ar.find(*i);
if (it != n2Ar.end()) {
list.insert(*i);
i = n1Ar.erase(i);
if(i == n1Ar.cend())
break;
n2Ar.erase(it);
} else {
for (set<int>::iterator i = n1Ar.begin(); i != n1Ar.end(); )
if ( n2Ar.erase(*i) || n3Ar.erase(*i) ) {
list.insert(*i);
n1Ar.erase(i++);
} else i++;
set<int> tmp;
std::set_union( n2Ar.begin(), n2Ar.end(),
n3Ar.begin(), n3Ar.end(), std::inserter(tmp,tmp.begin()) );
std::set_intersection( n1Ar.begin(), n1Ar.end(),
tmp.begin(), tmp.end(), std::inserter(list,list.begin()) );
std::copy( list.begin(), list.end(), std::ostream_iterator<int>(std::cout,"\n"));