我正在编写一个 Composite 类(类似于QObject
Qt),目前我将孩子存储在std::vector
. 每个 Composite 实例都有一个名称,并且该名称在作为该实例的兄弟的所有其他实例之间必须是唯一的,或者更好地说,在共享同一父级的实例之间必须是唯一的。
每次在 中推入一个新实例时vector
,我必须查看它的名称是否已被 中的一个实例使用vector
,如果是,我必须更改其名称并添加一个数字。
当孩子的数量变得一致时,我提出的代码非常愚蠢而且非常缓慢。
这是课程:
class Composite
{
public:
Composite(const std::string &name, Composite *ancestor=NULL);
~Composite();
private:
std::string name;
Composite *ancestor;
std::vector<Composite*> descendants;
public:
void setName(const std::string &name);
};
这是构造函数和setName
实现:
Composite::Composite(const std::string &name, Composite *ancestor)
{
this->ancestor = ancestor;
setName(name);
if (ancestor!=NULL)
ancestor->descendants.push_back(this);
}
.
void Composite::setName(const std::string &name)
{
this->name = name;
if (ancestor!=NULL)
{
CompositeList::iterator dIt;
for( dIt=ancestor->descendants.begin(); dIt!=ancestor->descendants.end(); dIt++)
{
if ((*dIt)==this)
{
continue;
}
else if (this->name == (*dIt)->getName())
{
int trailingNumber = stringToInt(getTrailingNumber(this->name));
std::string cleanName = removeTrailingNumber(this->name);
this->name = cleanName+intToString(trailingNumber+1);
}
}
}
}
这对于很少的孩子来说可能很好,但是当他们变成数百人时,setName
功能真的变得很慢。想象一下这种情况:
Composite *parent = new Composite("pippo");
for (int i=0; i<10000; i++)
{
Composite("ClashingName", parent);
}
第一次很好,第二次在 ClashingName0 中更改名称,第三次首先将名称更改为 ClashingName0,然后找到与第二个实例的冲突并将名称设置为 ClashingName1 ...你明白了,它是指数级的,当它到达该循环的末尾时,会经过一段不可接受的时间。
所以这里真正的问题是如何有效地找到冲突的名称并有效地分配一个尚未使用的新名称?任何标准容器对我来说都很好,我的编译器支持 C++11,但我不能/不想使用 Boost,因为我正在处理的项目非常小(基本上就是这个类)
我不是 C++ 的经验丰富的用户,我正在考虑使用map
,或者unordered_map
但我真的很想在这里获得专家的建议。