我会做这样的事情(显然你应该将它们映射到int,而不是字符串,并使用int作为代码)
struct structNode
{
std::set<std::string> sMachines;
std::map<std::string, int> mCodeToIndex;
std::vector<structNode> vChilds;
};
void Fill(std::string strIdMachine, int iIndex, structNode* pNode, std::vector<std::string> &vCodes)
{
if(iIndex < vCodes.size())
{
// Add "Empty" if Needed
if(pNode->vChilds.size() == 0)
{
pNode->mCodeToIndex.insert(pNode->mCodeToIndex.begin(), make_pair("empty", 0));
pNode->vChilds.push_back(structNode());
}
// Add for "Empty"
pNode->vChilds[0].sMachines.insert(strIdMachine);
Fill(strIdMachine, (iIndex + 1), &pNode->vChilds[0], vCodes );
if(vCodes[iIndex] == "empty")
return;
// Add for "Any"
std::map<std::string, int>::iterator mIte = pNode->mCodeToIndex.find("any");
if(mIte == pNode->mCodeToIndex.end())
{
mIte = pNode->mCodeToIndex.insert(pNode->mCodeToIndex.begin(), make_pair("any", pNode->vChilds.size()));
pNode->vChilds.push_back(structNode());
}
pNode->vChilds[mIte->second].sMachines.insert(strIdMachine);
Fill(strIdMachine, (iIndex + 1), &pNode->vChilds[mIte->second], vCodes );
// Add for "Segment"
mIte = pNode->mCodeToIndex.find(vCodes[iIndex]);
if(mIte == pNode->mCodeToIndex.end())
{
mIte = pNode->mCodeToIndex.insert(pNode->mCodeToIndex.begin(), make_pair(vCodes[iIndex], pNode->vChilds.size()));
pNode->vChilds.push_back(structNode());
}
pNode->vChilds[mIte->second].sMachines.insert(strIdMachine);
Fill(strIdMachine, (iIndex + 1), &pNode->vChilds[mIte->second], vCodes );
}
}
//////////////////////////////////////////////////////////////////////
// Get
//
// NULL on empty group
//////////////////////////////////////////////////////////////////////
set<std::string>* Get(structNode* pNode, int iIndex, vector<std::string> vCodes, int iMinValue)
{
if(iIndex < vCodes.size())
{
std::map<std::string, int>::iterator mIte = pNode->mCodeToIndex.find(vCodes[iIndex]);
if(mIte != pNode->mCodeToIndex.end())
{
if(pNode->vChilds[mIte->second].sMachines.size() < iMinValue)
return NULL;
else
return Get(&pNode->vChilds[mIte->second], (iIndex + 1), vCodes, iMinValue);
}
else
return NULL;
}
return &pNode->sMachines;
}
用您的样本填充树
structNode stRoot;
const char* dummy[] = { "city1", "switch03", "server01" };
const char* dummy2[] = { "city1", "switch03", "empty" };
const char* dummy3[] = { "city2", "switch03", "server02" };
const char* dummy4[] = { "city2", "switch04", "server02" };
// Fill the tree with the sample
Fill("node1", 0, &stRoot, vector<std::string>(dummy, dummy + 3));
Fill("node2", 0, &stRoot, vector<std::string>(dummy, dummy + 3));
Fill("node3", 0, &stRoot, vector<std::string>(dummy2, dummy2 + 3));
Fill("node4", 0, &stRoot, vector<std::string>(dummy2, dummy2 + 3));
Fill("node5", 0, &stRoot, vector<std::string>(dummy3, dummy3 + 3));
Fill("node6", 0, &stRoot, vector<std::string>(dummy3, dummy3 + 3));
Fill("node7", 0, &stRoot, vector<std::string>(dummy4, dummy4 + 3));
Fill("node8", 0, &stRoot, vector<std::string>(dummy4, dummy4 + 3));
现在您可以轻松获得所需的所有组合,例如您查询的内容如下:
vector<std::string> vCodes;
vCodes.push_back("empty"); // Discard first property (cities)
vCodes.push_back("any"); // Any value for infiniband
vCodes.push_back("any"); // Any value for networkfs (except empty)
set<std::string>* pMachines = Get(&stRoot, 0, vCodes, 2);
例如,只有交换机 03 上的 City02 网络不为空
vector<std::string> vCodes;
vCodes.push_back("city2"); // Only city2
vCodes.push_back("switch03"); // Only switch03
vCodes.push_back("any"); // Any value for networkfs (except empy)
set<std::string>* pMachines = Get(&stRoot, 0, vCodes, 2);