嗯,这取决于两个集合(ID* 和 foo*)的大小。我假设您有 #ID >> #FOO,并且 #FOO 大到足以保证通过它们进行线性搜索。
我假设 ID Foo 是一对多映射。
您可以将映射存储为一组 >> 并以这种方式对它们进行排序:
该集合按 ID* 的升序排序(指针值顺序可以)
set> 按对中第一个 ID* 的值的升序排序。第二个。
搜索时,您需要找到 Foo* 的范围,其中第一个 ID* 的(指针)值低于被搜索项,最后一个值更高。这将导致希望迭代它们的集合的项目集要小得多。
然后,遍历这些并找到包含您要查找的 ID* 的那个。
你需要一个比较器来匹配这对 > 像这样:
typedef Item pair<Foo*, set<ID*> >;
// Sorter in ascending order of first ID*, then ascending order of last ID*
struct IDOrdering: public binary_function<Item, Item, bool> {
bool operator ()(const Item& lhs, const Item& rhs) {
return *(lhs.second.begin()) < *(rhs.second.begin())
|| *(lhs.second.rbegin()) < *(rhs.second.rbegin());
}
};
// your global map
set<Item, FirstIDOrdering> myMap;
typedef set<Item, FirstIDOrdering>::iterator ItemIterator;
// search for the item
Foo* FindXXX(const ID* pId) {
Item criterion;
criterion.second.insert(pId);
ItemIterator start = myMap.lower_bound(criterion);
while (start != myMap.end() && *(start->second.rbegin()) > pId) {
if (start->second.count(pId))
return start->first;
}
return NULL;
}
您可以在这里节省一些内存,因为 Foo* 和 ID* 只存储一次,但它会以一些复杂性和可能的一些性能为代价。
请注意,此示例未考虑各种边界情况(空列表),并且在将新项目插入全局 myMap 时必须小心,因为您可能可以将新 ID* 添加到一对的列表,但您需要确保整个集合再次排序,以便查找真正起作用。
但是,很难知道什么最适合您,因为关于您尝试实现的目标的信息很少:数百万的 Foo*,数百万的 ID*,这个函数是将 ID* 解析为 Foo* 经常调用?在系统的性能关键部分?所有这些都有助于权衡代码的可读性、复杂性和性能。