Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从集合中删除元素时出现问题_C++_Set_Erase - Fatal编程技术网

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"));