Ankush
Ankush

Reputation: 6927

set_union issue while using arrays

I am trying to get union of 4 arrays using set_union. Here is the code I have so far:

int setA[5] = {2, 4, 5, 7, 8};
int setB[7] = {1, 2, 3, 4, 5, 6, 7};
int setC[5] = {2, 5, 8, 8, 15};
int setD[6] = {1, 4, 4, 6, 7, 12};

int AunionB[12];
int CunionD[11];
int finalUnion[23];

int *lastAunionB;
int *lastCunionD;

ostream_iterator<int> screen(cout, " ");

lastAunionB = set_union(setA, setA+5, setB, setB+7, AunionB);

cout << "AunionB = ";
copy(AunionB, lastAunionB, screen);
cout << endl;

lastCunionD = set_union(setC, setC+5, setD, setD+6, CunionD);

cout << "CunionD = ";
copy(CunionD, lastCunionD, screen);
cout << endl;

set_union(AunionB, AunionB+12, CunionD, CunionD+11, finalUnion);

cout << "Final Union = ";
copy(finalUnion, finalUnion+23, screen);
cout << endl;

When I ran the code, I got the following output:

AunionB = 1 2 3 4 5 6 7 8 
CunionD = 1 2 4 4 5 6 7 8 8 12 15 
Final Union = 1 2 3 4 5 6 7 2 4 4 5 6 7 8 8 12 15 52187240 1 1863041424 32767 0 0 

Therefore, the unions of setA and setB works as intended as does the union of setC and setD. However, when I try to get the union of all for sets, it doesn't work! I'm guessing the last 5 values of finalUnion are the address fields but how do I remove them? Also, the union itself is incorrect and I can't understand why.

Upvotes: 0

Views: 267

Answers (2)

Eric J.
Eric J.

Reputation: 150108

A Union operation removes values that the two sets have in common.

Note that AUnionB has 8 elements (not the 12 that your code predicts).

You need to adjust your union-of-union code to account for the actual size of the two initial unions. You have everything prepared to do it correctly:

int *lastFinalUnion = set_union(AunionB, lastAunionB, CunionD, lastCunionD, finalUnion);

Note that set C has two distinct occurrences of 8 and set D has two distinct occurrences of 4, which is why they appear duplicated in the intermediate result.

UPDATE

Also, I tried your code and i'm getting the answer as 1 2 3 4 5 6 7 2 4 4 5 6 7 8 8 12 15 . Shouldn't the answer be 1 2 3 4 4 5 6 7 8 8 12 15

I believe you are correct, but I'm not in front of a C++ compiler to step through and see what's doing on, or to verify your output. The actual code was edited in by another SO member, but it looks correct to me.

In the simplest case, set_union performs the "union" operation from set theory: the output range contains a copy of every element that is contained in [first1, last1), [first2, last2), or both. The general case is more complicated, because the input ranges may contain duplicate elements. The generalization is that if a value appears m times in [first1, last1) and n times in [first2, last2) (where m or n may be zero), then it appears max(m,n) times in the output range.

https://www.sgi.com/tech/stl/set_union.html

Upvotes: 1

AdamF
AdamF

Reputation: 2601

The size of the AunionB and Cuniond is not 12 and 11 because:

Elements from the second range that have an equivalent element in the first range are not copied to the resulting range.

Try this code:

int setA[5] = { 2, 4, 5, 7, 8 };
int setB[7] = { 1, 2, 3, 4, 5, 6, 7 };
int setC[5] = { 2, 5, 8, 8, 15 };
int setD[6] = { 1, 4, 4, 6, 7, 12 };

int AunionB[12];
int CunionD[11];
int finalUnion[23];

int *lastAunionB;
int *lastCunionD;

ostream_iterator<int> screen(cout, " ");

lastAunionB = set_union(setA, setA + 5, setB, setB + 7, AunionB);

cout << "AunionB = ";
copy(AunionB, lastAunionB, screen);
cout << endl;

lastCunionD = set_union(setC, setC + 5, setD, setD + 6, CunionD);

cout << "CunionD = ";
copy(CunionD, lastCunionD, screen);
cout << endl;

int *finalUnionEnd;
finalUnionEnd = set_union(AunionB, lastAunionB, CunionD, lastCunionD, finalUnion);

cout << "Final Union = ";
copy(finalUnion, finalUnionEnd, screen);
cout << endl;

And then you got the right result:

Final Union = 1 2 3 4 4 5 6 7 8 8 12 15

Upvotes: 1

Related Questions