我有以下数据结构:
set< pair<int, int> > data;
data = {<1, 1> ; <3, 2> ; <5, 5> ; <5, 4> ; <4, 2>, <1, 8>, <9, 9> }
我想合并包含至少一个公共元素的对,并将结果存储在集合的矢量中。
vector< set<int> > result;
result = [ {1, 8} ; {2, 3, 4, 5} ; {9} ]
我知道<algorithm>
中有一个set_union,但我们如何计算&#34; union&#34;对?谢谢!
答案 0 :(得分:3)
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::set<std::pair<int,int> > SetOfPair;
和
struct pair_equal : std::unary_function< std::pair<int,int>, bool> {
pair_equal(const int &idx) : idx_(idx) {}
bool operator()(const std::pair<int,int> &arg) const { return
( arg.first == idx_) || ( arg.second == idx_); }
const int &idx_;
};
std::set<int> connected_component( SetOfPair& sp) {
std::vector<int> componentIndices;
componentIndices.push_back( (*(sp.begin())).first);
componentIndices.push_back( (*(sp.begin())).second);
int indexCount = 2;
int currIdx = 0;
SetOfPair::const_iterator it;
while ( currIdx < indexCount) {
while ( ( it = std::find_if( sp.begin(), sp.end(), pair_equal(
componentIndices[ currIdx]))) != sp.end()) {
/* new reachable index connected to this component found */
int newIdx = ( componentIndices[ currIdx] ==
(*it).first? (*it).second : (*it).first);
/* insert if not present already */
if ( std::find( componentIndices.begin(),
componentIndices.end(), newIdx) == componentIndices.end()) {
componentIndices.push_back( newIdx);
++indexCount;
}
sp.erase( it);
}
++currIdx;
}
return std::set<int>( componentIndices.begin(), componentIndices.end());
}
和
int make_connected_components( SetOfPair sp,
std::vector<std::set<int> >& result) {
int componentCount = 0;
while( !sp.empty()) {
std::set<int> component = connected_component( sp);
result.push_back( component);
++componentCount;
}
return componentCount;
}
用法:
int main(int argc, char** argv) {
SetOfPair sp;
sp.insert( std::make_pair<int, int>( 1, 1));
sp.insert( std::make_pair<int, int>( 3, 2));
sp.insert( std::make_pair<int, int>( 5, 5));
sp.insert( std::make_pair<int, int>( 5, 4));
sp.insert( std::make_pair<int, int>( 4, 2));
sp.insert( std::make_pair<int, int>( 1, 8));
sp.insert( std::make_pair<int, int>( 9, 9));
std::vector<std::set<int> > components;
int numberOfComponents = make_connected_components( sp, components);
/* results */
std::cout << "numberOfComponents:" << numberOfComponents << std::endl;
std::vector<std::set<int> >::iterator it = components.begin();
while ( it != components.end()) {
std::copy( (*it).begin(), (*it).end(),
std::ostream_iterator<int>( std::cout, ":"));
std::cout << std::endl;
++it;
}
return 0;
}
输出:
numberOfComponents:3
1:8:
2:3:4:5:
9:
RUN SUCCESSFUL(总时间:61ms)
答案 1 :(得分:1)
正如Jarod42指出的那样,您需要边缘列表定义的图形的连通组件。以下是使用STL的方法。
构造一个邻接列表:一个map<int, set<int> >
,它将每个整数映射到它在一对中共同出现的整数集。这可以通过对向量的一次迭代来完成,将.second
添加到.first
的集合并将.first
添加到.second
。
深度优先遍历邻接列表。这有点复杂。初始化vector<set<int> >
。保留一个set<int>
,最初为空,表示已处理的整数。循环访问邻接列表的条目。对于未出现在已处理集合中的每个整数键,按如下所示构造下一个组件并将其推回到向量上,然后将处理后的整数集合与组件进行联合更新。
使用2中的整数键初始化stack<int>
。初始化空的set<int>
,即当前连接的组件。虽然堆栈不是空的,但抓住它的顶部整数然后弹出它。如果此整数未出现在组件中,请执行以下操作。将整数插入组件,然后在邻接列表中查找并将其所有邻居推入堆栈。