C++;STL";“关联集/映射”; 我正在寻找一种特殊的SET/MAP的名称,希望有一些现有的代码,如C++ STL。
调用集合C++;STL";“关联集/映射”; 我正在寻找一种特殊的SET/MAP的名称,希望有一些现有的代码,如C++ STL。,c++,algorithm,stl,map,set,C++,Algorithm,Stl,Map,Set,调用集合A 我想运行以下命令: A.associate(3,5) A.associate(3,6) A.associate(6,8) A.associate(8,10) A.associate(4,9) 然后能够提出以下问题,并收到指示的答案: A.is_associated(3,5) -> True A.is_associated(5,10) -> True A.is_associated(10,3) -> True A.is_associated(4,10) ->
A
我想运行以下命令:
A.associate(3,5)
A.associate(3,6)
A.associate(6,8)
A.associate(8,10)
A.associate(4,9)
然后能够提出以下问题,并收到指示的答案:
A.is_associated(3,5) -> True
A.is_associated(5,10) -> True
A.is_associated(10,3) -> True
A.is_associated(4,10) -> False
你知道这种构造/集合的名称吗
您知道是否存在现有的C/C++实现吗?一般来说,我认为此数据结构是一个图形:即,在您的情况下,使用整数标识的一组节点,以及可能是有向节点对的一组边。根据您的具体需要,有许多方法来表示和绘制图形。Boost有许多典型的图形数据结构,以及一系列在其上运行的算法
根据注释中的一些说明:
是关联的()
操作是无向图中的路径搜索。根据图形的需要,可以添加edge来表示数据结构,以便与之关联()
是常数时间,而插入的成本是线性时间。编辑:如果您想执行额外的步骤,您应该考虑有效地实现
不幸的是,我看到的唯一明智的方法是在std::set
上创建一个std::map
——每次插入时都需要检查这两个元素是否在不同的子集中——如果是,就合并它们
因此外部集合存储所有元素并将它们指向它们所属的集合
现在,如果添加新关联:
typedef std::map< int, std::set< int >& > assoc_set; // note that you need to
// store the sets somewhere else, maybe in another set
typedef std::map&>assoc_set;//请注意,您需要
//把电视机放在别的地方,也许是另一台
可能是这样的:
class assoc_set
{
typedef std::set< int > int_set;
typedef std::set< int_set > int_set_set;
typedef std::map< int, int_set_set::iterator > set_map;
public:
void associate( int a, int b )
{
set_set_map::iterator ia = iss.find( a );
set_set_map::iterator ib = iss.find( b );
if ( ia == set_set_map::end() )
{
if ( ib == set_set_map::end() )
{
// create new
int_set ab;
ab.insert(a);
ab.insert(b);
int_set_set::iterator r = iss.insert( ab ).second;
smap[a] = r;
smap[b] = r;
}
else
{
// add to a
smap[a] = ib;
ib->insert( a );
}
}
else
{
if ( ib == set_set_map::end() )
{
// add to b
smap[b] = ia;
ia->insert( b );
}
else
{
// merge
ia->insert( ib->begin(), ib->end() );
// this could be done better
for ( int_set::iterator i = it->begin(); i != it->end(); ++i )
{
smap[*i] = ia;
}
}
}
}
bool is_associated( int a, int b )
{
set_set_map::iterator ia = iss.find( a );
set_set_map::iterator ib = iss.find( b );
return ia != set_set_map::end() && ia = ib;
}
private:
int_set_set iss;
set_map smap;
}
类关联集合
{
typedef std::setO(n)
(但可以通过使用额外的间接层(并摆脱愚蠢的映射循环)减少为O(log(n))
。查询是O(log(n))
使用
unordered\u set/unordered\u map
您可能会将两者都减少到O(1)
摊销。为什么A.is\u关联(5,10)
true?你能更详细地解释一下关联逻辑吗?顺序是5->3->6->8->10
。似乎没有人理解这个问题:/Ah,所以这是一个双向关联,人们可以根据需要遵循链。是的,我会称之为无向图。我将在将来删除我的答案。OP请更仔细地解释您的要求。@PlatinumAzure,我觉得问题很清楚,没有假设要提出一个潜在的结构,也没有可能对答案产生偏见。如果您正在为此制定一个答案,我深表歉意-感谢您的帮助。如果您想要快速、轻量的施工,这个解决方案很好,但您愿意接受慢速查询。如果您想要快速查询(以较慢的构造和更多的空间需求为代价)你最好使用集合地图。@KornelKisielewicz你可以这样做:如果你想有很多更改和很少的查询,你每次都要进行路径搜索。如果你有很多查询和很少的更改,你可以在更改后设置图形:有很多方法来表示根据特定新闻定制的图形。事实上,集合地图同构于gr想一想,这不是一个图,而是一个不相交的集合。是的,可能是有用的东西。我倾向于认为这是一个使用的图算法,例如在所有对最短路径中。