简体   繁体   English

C ++从循环中的向量中删除元素

[英]C++ Remove element from vector in loop

I am trying to implement Set Class in C ++ (on Home exercise).我正在尝试在 C++ 中实现 Set Class(在家庭练习中)。 I would like overloading operator - = for sets subtraction.我想重载运算符 - = 用于集减法。 Some times function return good result, but sometimes digits from set s2 are in set s1.有时函数返回好的结果,但有时来自集合 s2 的数字在集合 s1 中。 Moreover, if you could check out the copy constructor?此外,如果您可以检查复制构造函数? And tell me and tell me if it should be like this using vectors in Class.并告诉我并告诉我在 Class 中使用向量是否应该是这样的。 And if in Class i have vector, i have to write something in destructor?如果在类中我有向量,我必须在析构函数中写一些东西吗? Thank You for Help!谢谢你的帮助! (vector is public for tests) (向量对于测试是公开的)

My code is:我的代码是:

#include <ctime>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;

class Set
{
    int n;

public:
    vector <int> set;
    Set(int n)
    {
        for(int i=0; i<n; i++)
        {
            set.push_back(rand()%11);
        }
        this->n = set.size();
        remove_duplicates();
    }
    Set(const Set& obj)
    {
        n=obj.n;
        set.clear();
        for(int i=0; i<n; i++)
        {
            set.push_back(obj.set[i]);
        }
    }
    Set& operator-=(const Set& obj)
    {
        for(auto it = set.begin(); it !=set.end(); it++)
        {
            for(int j=0; j<obj.set.size(); j++)
            {
                if(set[*it]==set[j])
                {
                    it = set.erase(it);
                }
            }
        }
        return * this;
    }
    void remove_duplicates()
    {
        sort( set.begin(), set.end() );
        set.erase( unique( set.begin(), set.end() ), set.end() );
        n = set.size();
    }
    void print()
    {
        for(int i=0; i<set.size(); i++)
        {
            cout << set[i] << " ";
        }
        cout << endl;
    }
};

int main()
{
    srand(time(nullptr));
    Set s1(5);
    Set s2(5);
    s1.print();
    s2.print();
    cout << endl;
    s1-=s2;
    s1.print();
}

example result;示例结果;

2 3 6 7 9
1 3 7 9

6 7 9

and good result和好的结果

1 3 5 6 7
2 4 9 10

5 6 7

The loop in operator-= is implemented wrong. operator-=中的循环执行错误。

You are incrementing the it iteration on all loop iterations unconditionally, even on iterations that are erase() 'ing elements, thus you end up skipping elements.您正在无条件地在所有循环迭代中增加it迭代,即使是在erase()元素的迭代中,因此您最终会跳过元素。

Also, you are using the element values of the target vector as indexes into that vector , which is wrong.此外,您使用目标vector的元素值作为该vector的索引,这是错误的。 And though you are looping through the source vector , you are not actually indexing into that vector 's elements at all.尽管您正在遍历源 vec vector vector元素。

Try this instead:试试这个:

Set& operator-=(const Set& obj)
{
    auto it = set.begin();
    while (it != set.end())
    {
        bool erased = false;
        for(int value : obj.set)
        {
            if (*it == value)
            {
                it = set.erase(it);
                erased = true;
                break;
            }
        }
        if (!erased)
            ++it;
    }
    return *this;
}

Which can then be simplified using std::find() , eg:然后可以使用std::find()进行简化,例如:

Set& operator-=(const Set& obj)
{
    auto it = set.begin();
    while (it != set.end())
    {
        if (std::find(obj.set.begin(), obj.set.end(), *it) != obj.set.end())
            it = set.erase(it);
        else
            ++it;
    }
    return *this;
}

Alternatively:或者:

Set& operator-=(const Set& obj)
{
    for(int value : obj.set)
    {
        auto found = std::find(set.begin(), set.end(), value);
        if (found != set.end())
            set.erase(found);
    }
    return *this;
}

Or, you can use std::remove_if() instead, eg:或者,您可以使用std::remove_if()代替,例如:

Set& operator-=(const Set& obj)
{
    set.erase(
        std::remove_if(
            set.begin(), set.end(),
            [&](int value){
                return std::find(obj.set.begin(), obj.set.end(), value) != obj.set.end();
            }
        ),
        set.end()
    );
    return *this;
}

Also, your n class member is unused outside of your constructors, so it should not be in the class at all.此外,您的n类成员在构造函数之外未使用,因此它根本不应该在类中。 You already know that you can use set.size() where needed.您已经知道可以在需要的地方使用set.size()

Also, your copy constructor can be greatly simplified by using vector 's copy constructor, in which case you can actually eliminate your copy constructor altogether and let the compiler auto-generate it for you.此外,您的复制构造函数可以通过使用vector的复制构造函数大大简化,在这种情况下,您实际上可以完全消除您的复制构造函数并让编译器为您自动生成它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM