私は Composite クラス ( QObject
Qt に似ています) をコーディングしていますが、現時点では、子をstd::vector
. 各 Composite インスタンスには名前があり、この名前は、このインスタンスの兄弟である他のすべてのインスタンス間で一意である必要があります。同じ親を共有するインスタンス間で、より適切に表現する必要があります。
新しいインスタンスが 内にプッシュされるたびに、vector
その名前が 内のインスタンスの 1 つによって既に使用されているかどうかを確認する必要があります。使用されている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);
}
1 回目は問題なく、2 回目は名前が ClashingName0 で変更され、3 回目は名前が最初に ClashingName0 に変更され、2 番目のインスタンスとの衝突が検出され、名前が ClashingName1 に設定されます...それは指数関数的であり、そのループの終わりに来ると、許容できない時間が経過します。
ここでの本当の問題は、衝突する名前を効率的に見つけて、まだ使用されていない新しい名前を効率的に割り当てる方法です。どんな std コンテナでも問題なく、私のコンパイラは C++11 をサポートしていますが、私が取り組んでいるプロジェクトが信じられないほど小さいため (基本的にはこのクラスです)、Boost を使用できない/使用したくありません。
私は C++ のベテラン ユーザーではありません。 map
orを使用することを考えていましunordered_map
たが、ここで専門家の提案に本当に飢えています。