0

我正在尝试使用 set_union 获得 4 个数组的联合。这是我到目前为止的代码:

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;

当我运行代码时,我得到以下输出:

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 

因此,setA and setB作品的联合与setC and setD. 但是,当我尝试获得所有集合的并集时,它不起作用!我猜最后 5 个值finalUnion是地址字段,但如何删除它们?另外,工会本身是不正确的,我不明白为什么。

4

2 回答 2

1

联合操作会删除两个集合共有的值。

请注意, AUnionB 有 8 个元素(不是您的代码预测的 12 个)。

您需要调整工会代码以考虑两个初始工会的实际大小。您已准备好正确执行此操作:

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

请注意,集合 C 有两次不同的 8,而集合 D 有两次不同的 4,这就是它们在中间结果中出现重复的原因。

更新

另外,我尝试了您的代码,得到的答案是 1 2 3 4 5 6 7 2 4 4 5 6 7 8 8 12 15 。答案不应该是 1 2 3 4 4 5 6 7 8 8 12 15

我相信你是对的,但我不是在 C++ 编译器面前单步执行,看看正在做什么,或者验证你的输出。实际代码是由另一个 SO 成员编辑的,但对我来说看起来是正确的。

在最简单的情况下,set_union 执行集合论中的“联合”操作:输出范围包含 [first1, last1)、[first2, last2) 或两者中包含的每个元素的副本。一般情况更复杂,因为输入范围可能包含重复元素。概括地说,如果一个值在 [first1, last1) 中出现 m 次,在 [first2, last2) 中出现 n 次(其中 m 或 n 可能为零),则它在输出范围内出现 max(m,n) 次。

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

于 2015-05-04T18:12:28.093 回答
1

AunionB 和 Cuniond 的大小不是 12 和 11,因为:

第二个范围中在第一个范围内具有等效元素的元素不会复制到结果范围内。

试试这个代码:

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;

然后你得到了正确的结果:

Final Union = 1 2 3 4 4 5 6 7 8 8 12 15
于 2015-05-04T18:16:28.997 回答