remove common elements from two vectors

hello
i made a code to remove all common elements in two vectors of objects.
firt i'd like to know if is there any more elegant way to do it, and if i made something wrong;
and second, why is "Destructor" called so many times?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <vector>
#include <algorithm>

class A{
public:
    int n;
    A(int integer){
        std::cout << "Constructor\n";
        n = integer;
    }
    ~A(){
        std::cout << "Destructor\n";
    }

    bool operator < (A& a){
        if (n < a.n){
            return true;
        }
        else{
            return false;
        }
    }
};

void int main(){
    std::vector<A> a1 = {1, 2, 3, 4, 5};
    std::getchar();
    std::vector<A> a2 = {4, 5, 6, 7, 8};

    std::getchar();
    if(a1[0] < a2[0]){
        std::cout << "a1[0] < a2[0]\n";
    }

    std::vector<A> inter;
    std::set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), std::back_inserter(inter));
    a1.erase(std::set_difference(a1.begin(), a1.end(), inter.begin(), inter.end(), a1.begin()), a1.end());
    a2.erase(std::set_difference(a2.begin(), a2.end(), inter.begin(), inter.end(), a2.begin()), a2.end());

    std::getchar();
    std::cout << "a1:";
    for (auto v : a1){
        std::cout << v.n << ",";
    }
    std::cout << "a2:";
    for (auto v : a2){
        std::cout << v.n << ",";
    }
    
    return 0;
}


thanks in advance! :)
Use std::set_symmetric_difference: http://en.cppreference.com/w/cpp/algorithm/set_symmetric_difference

why is "Destructor" called so many times?

turn on the copy ctor as well and it'd show where the copies are being made and hence there are (seemingly) additional calls to the dtor. In this regard, the following thread might be of interest:
http://www.cplusplus.com/forum/beginner/218759/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# include <iostream>
# include <vector>
# include <algorithm>
# include <iterator>
# include <utility>

class A
{
public:
    int n;
    A(int integer): n(integer){
        std::cout << "Constructor " << n << "\n";
       // n = integer;
    }
    A(const A&a) : n(a.n) {std::cout << "copy ctor " << a.n << "\n";}
    ~A(){
        std::cout << "Destructor " << n << "\n";
    }

    bool operator < (A& a){
        if (n < a.n){
            return true;
        }
        else{
            return false;
        }
    }
};

std::ostream& operator << (std::ostream& os, const A& a)
{
    os << a.n;
    return os;
}

int main(){
    std::vector<A> a1 {1, 2, 3, 4, 5};

    std::cout << "end of a1 initialization \n\n";

    std::vector<A> a2 = {4, 5, 6, 7, 8};

    std::cout << "end of a2 initialization \n\n";

    std::cout << "start of sorting a1 \n\n";

    std::sort(a1.begin(), a1.end());

    std::cout << "\nstart of sorting a2 \n\n";
    std::sort(a2.begin(), a2.end());

    std::cout << "end of sorting a2\n\n";

    std::vector<A> a_SymDiff_b{};

     std::cout << "start of std::set_sym_diff " << "\n\n";
     std::set_symmetric_difference(
        a1.begin(), a1.end(),
        a2.begin(), a2.end(),
        std::back_inserter(a_SymDiff_b));

    std::cout << "\nend of std::set_sym_diff " << "\n\n";

    for (const auto& elem : a_SymDiff_b)
    {
        std::cout << elem << "\n";
    }
    std::cout << "\nend of printing \n\n";

}

[first I'd] like to know if is there any more elegant way to do it, and if i made something wrong
I think your code works, and that's the best optimization of all. I suspect it could be done more efficiently by hand, but it's much more likely that you'd get it wrong that way.
second, why is "Destructor" called so many times?

One reason is that lines 43 and 47 make copies of each element. Change auto v to auto v&.
Otherwise the destructor is called as many times as the constructor. You aren't seeing this because many instances are built with the compiler-generated copy constructor. Here is a modified version with a copy constructor and above-mentioned references:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <vector>
#include <algorithm>

using std::cout;

class A{
public:
    int n;
    A(const A& rhs) {
	n = rhs.n;
	std::cout << "Copy\n";
    }
    A(int integer){
        std::cout << "Constructor\n";
        n = integer;
    }
    ~A(){
        std::cout << "Destructor\n";
    }

    bool operator < (A& a){
        if (n < a.n){
            return true;
        }
        else{
            return false;
        }
    }
};

int main(){
    std::vector<A> a1 = {1, 2, 3, 4, 5, 7};
    cout << "built a1\n";
    std::vector<A> a2 = {2, 4, 5, 6, 7, 8};
    cout << "built a2\n";

    if(a1[0] < a2[0]){
        std::cout << "a1[0] < a2[0]\n";
    }

    cout << "built vectors\n";
    std::vector<A> inter;
    std::set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), std::back_inserter(inter));
    cout << "did intersection\n";
    a1.erase(std::set_difference(a1.begin(), a1.end(), inter.begin(), inter.end(), a1.begin()), a1.end());
    cout << "erased from a1\n";
    a2.erase(std::set_difference(a2.begin(), a2.end(), inter.begin(), inter.end(), a2.begin()), a2.end());

    cout << "erased from a2\n";
    std::cout << "a1:";
    for (auto &v : a1){
        std::cout << v.n << ",";
    }
    std::cout << "\na2:";
    for (auto &v : a2){
        std::cout << v.n << ",";
    }
    
    return 0;
}

why is "Destructor" called so many times?

What do you mean by "so many"? The destructor will be called once for every instance of your class that is created. How many times do you think the copy or assignment operators being called?

What are you trying to do with this line?
void int main(){

And why all the unannounced getchar() calls?

thanks everybody for the answers.

One reason is that lines 43 and 47 make copies of each element. Change auto v to auto v&.
thanks, i'll use the suggestion!

Use std::set_symmetric_difference: http://en.cppreference.com/w/cpp/algorithm/set_symmetric_difference

it does not seems to work for me. in your example, you have a new vector (a_SymDiff_b) that contains all elements that were exclusive to a1 and all exclusive to a2; but i need 2 separated vectors, each one with its own elements.

What do you mean by "so many"?
i mean that this code calls constructors 5 times and destructors 10 times. shouldn't it be 5 times each?
1
2
3
4
int main(){
    std::vector<A> a1 = {1, 2, 3, 4, 5};
    return 0;
}


What are you trying to do with this line?
void int main(){

thats a typo :)

And why all the unannounced getchar() calls?

it justs stops the program until i press something, so i can see whats happening. better than debuging in this case, i think...
Last edited on
i mean that this code calls constructors 5 times and destructors 10 times. shouldn't it be 5 times each?

Repeating from my earlier answer:
You aren't seeing this because many instances are built with the compiler-generated copy constructor.

If you run the version that I posted, you'll see the same number of constructor destructor calls.
oh, i got it. thanks for the answer :)
Topic archived. No new replies allowed.