我正在解决一个非常具体的问题,需要使用数据结构来存储和跟踪对象。使用一个简单的例子,假设我有以下两个类:
class Foo
{
Foo Foo(bool isRed) {m_bRed = isRed} ;
bool m_bRed;
}
class Bar
{
Bar Bar(Foo* pFoo) {m_pFoo = pFoo} ;
Foo * m_pFoo;
}
随着程序的运行,将会创建许多Foos和Bars,并且在程序终止时,我想知道有多少条是红色的(从它包含Foo)。请假设这两个类都没有getter / setter,解决这个问题的唯一方法就是挂钩Foo&Bar和构造函数。现在,做这个的最佳数据结构是什么?
我认为一个潜在的解决方案是使用以下格式的两张(无序)地图:
std::map<Foo*, bool> g_FooContainers;
std::map<Bar*, bool> g_BarContainers;
当创建Foo时,我们将其插入到地图中,
g_FooContainers.insert(std::make_pair(Foo*, isRed));
当创建Bar时,我们在其地图中查找传入的Foo *,如果找到,则将Bar插入其地图中并使用相应的isRed。
r = g_FooContainers.find(Foo*);
if (r != unordered_map::end)
{
g_BarContainers.insert(std::make_pair(Bar*, r->second)));
}
在程序执行结束时,我们可以遍历g_BooContainers并查看哪个Bar是红色的。
现在,我想知道是否有更有效的方法来做到这一点?也许只有一个std :: map?
请告诉我。
答案 0 :(得分:0)
我建议:
Bar*
。Bar*
添加到构造函数中的集合。Bar*
。Bar*
集并从中收集Foo*
集。我假设在没有删除带有指向它的Foo
的情况下不会删除Bar
。这可以确保如果有多个Bar
指向同一个Foo
,则您不会多次计算它。Foo*
集进行迭代,并计算red
的数量。示例代码
std::set<Bar*> g_aliveBars;
class Bar
{
Bar(Foo* pFoo) {m_pFoo = pFoo; g_aliveBars.insert(this);}
~Bar() {g_aliveBars.erase(this);}
Foo * m_pFoo;
}
int getRedFoos()
{
std::set<Foo*> aliveFoos;
for ( auto bar: g_aliveBars )
{
aliveFoos.insert(bar->m_pFoo);
}
int count = 0;
for ( auto foo; aliveFoos)
{
count += (foo->m_bRed? 1 : 0);
}
return count;
}
如果没有类中的getter和setter,我希望您能提供一种机制来从Foo*
获取Bar
。您可以通过保留Boo*
- &gt;的地图来实现这一目标。 Foo*
。同样,您可以提供一种机制来回答Foo
是否为红色。从本质上讲,您需要:
std::map<Foo*, bool> g_FooIsRedMap;
std::map<Bar*, Foo*> g_BarToFooMap;
鉴于此,getRedFoos()
可以翻译为:
int getRedFoos()
{
std::set<Foo*> aliveFoos;
for ( auto bar: g_aliveBars )
{
aliveFoos.insert(getFoo(bar));
}
int count = 0;
for ( auto foo; aliveFoos)
{
count += (isRed(foo)? 1 : 0);
}
return count;
}