在C ++中合并联合集

时间:2013-07-22 11:31:30

标签: c++ vector set intersection

unsigned int ...

的向量向量开始
vector<vector<unsigned short int> > matrix;
vector<unsigned short int> row;

我想合并联合集(即具有共同元素的向量)。

对于istance,作为输入:

matrix[0] = {0, 1, 2}
matrix[1] = {1, 10}
matrix[3] = {9}
matrix[4] = {2, 8}
matrix[5] = {7}

作为输出:

matrix[0] = {0, 1, 2, 10, 8}  // it doesn't matter the order
matrix[1] = {9}
matrix[2] = {7}

这个问题最有效的解决方案是什么? 最好的问候,Vi。

2 个答案:

答案 0 :(得分:2)

您可以将此问题减少为查找无向图的所有连接组件。顶点是矩阵行,边缘是非零重叠。 Boost.Graph库可以O(V+E)复杂度计算此值,其中V是数字顶点(矩阵行)和E边数(重叠行数)。如果你不喜欢Boost的依赖,你可以使用任何available algorithms来计算强连接组件。

剩下的是计算此图的边列表表示,这取决于您是否能够对矩阵行进行排序。如果无法对矩阵行进行排序,则可以使用std::find_first_of检测非零重叠(O(N * M)N元素的2个向量的复杂度为M。如果您可以对它们进行排序(复杂度为O(N lg N)),则可以使用std::set_intersection来测试重叠(仅O(N + M)复杂度)。

Boost.Graph或您的算法的输出是一组连接的组件,然后循环遍历每个组件并将矩阵的各个重叠行追加或合并(使用std::copy或{{ 1}}如果你需要它们排序。)

答案 1 :(得分:1)

我建议你使用disjoint set forest。对于每个集合,迭代地将数字添加到集合的第一个数字所属的集合中。完成后,只需打印每组中的所有数字。实际上,实现并不是那么难,但性能将比已经提出的解决方案快得多。