需要使用两个键快速查找对象

时间:2015-02-17 12:31:46

标签: c++ stl

在C ++中,有一个可以根据两个键搜索到的对象存储的惯用方法是什么?基本上我想要的是将类型A的东西存储在二叉搜索树(BST)中,其中BST使用A.key上的顺序关系构造。但是,每个A也有一个唯一的A.otherval,我基本上需要根据这个值删除密钥。

在C中,我通常只有一个带有父指针的BST和一个基于其他值的哈希表作为存储指向BST节点的指针的键。我可以通过获取节点并在该节点上调用树删除来通过哈希表删除密钥。

我正在寻找如何使用STL容器正确执行此操作。

2 个答案:

答案 0 :(得分:1)

如果我正确地得到了问题,那么您需要的只是地图中的map,所以

std::map<first_key_type, std::map<second_key_type, value_type>> map;
map[key1][key2] = something;

编辑:

我假设具有相同第一个键的所有值都相同,而第二个键仅用作其他搜索/删除条件。在这种情况下,要仅通过第一个键获取值,您可以使用类似

的内容
map.at(key).cbegin()->second;

答案 1 :(得分:0)

我建议使用两张地图,一张用于将密钥映射到A(主要地图)的实例,另一张用于将otherVal映射到密钥:

typedef ... Key;
typedef ... OtherVal;
struct A { Key key; OtherVal otherVal; ... };

typedef std::map<Key,A> KeyToAMap;
typedef std::map<OtherVal,Key> OtherValToKeyMap;

KeyToAMap keyToAMap;
OtherValToKeyMap otherValToKeyMap;

通过这种方式,您可以使用keyToAMap而无需任何额外的复杂性,但是当需要删除时,您只需要额外的查找。

为了方便使用,我还建议在两个地图中编写用于包装插入和删除的功能:

void insertNewA(const A& a) {
    keyToAMap.insert(std::make_pair(a.key, a ));
    otherValToKeyMap.insert(std::make_pair(a.otherVal, a.key ));
}

void deleteByOtherVal(const OtherVal& otherVal) {
    OtherValToKeyMap::iterator it1 = otherValToKeyMap.find(otherVal);
    if (it1 == otherValToKeyMap.end()) { /* error */ }
    Key& key = it1->second;
    KeyToAMap::iterator it2 = keyToAMap.find(key);
    if (it2 == keyToAMap.end()) { /* error */ }
    keyToAMap.erase(it2);
    otherValToKeyMap.erase(it1);
}

此解决方案的一个优点是它只需要两个地图,而不是需要1 + N个地图的多级地图解决方案,其中N是主地图中的条目数。