用于查找到元素集的id映射的良好数据结构(c ++)

时间:2009-06-23 19:12:08

标签: c++ algorithm stl

没有提升,请简单的STL。

我有一个类Foo *映射到一组类ID的指针。

我需要将指向ID实例的指针映射到FOO类。

说我有这个功能:

void FindXXX(const ID* pID)
{

 /*find the containing FOO class quickly, but not at expense of an ugly code*/

}

现在我将每个ID *映射到FOO *,因此具有类似的东西

映射myMap;我认为这有点丑陋和多余。

请建议

3 个答案:

答案 0 :(得分:1)

听起来像std :: map的工作,但是你的言论似乎表明你不想使用它,是真的吗?

std::map <key_type, data_type, [comparison_function]>

答案 1 :(得分:1)

  

现在我将每个ID *映射到FOO *   有这样的东西

     

映射myMap;我觉得有点儿   丑陋和多余。

我认为你有类似的东西:

map<ID*, Foo*> myMap;

为什么会这么丑?

答案 2 :(得分:0)

嗯,这取决于两组的大小(ID *和foo *)。我假设你有#ID&gt;&gt; #FOO和#FOO足够大,不能保证通过它们进行线性搜索。

我假设ID&lt; - &gt; Foo是1对多的映射。

您可以将映射存储为一组&gt; &GT;并按这种方式排序: 集合按ID *的递增顺序排序(指针值顺序可以正常) 集&gt;按对象的.second中第一个ID *的值的升序排序。

搜索时,您需要找到具有一组的Foo *的范围,其中第一个ID *的(指针)值低于搜索的项目,最后一个值更高。这将导致希望更小的一组项目迭代它们的集合。 然后,迭代这些并找到包含您正在寻找的ID *的那个。

你需要一对比较器&gt;像这样:

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 *一对&lt;&gt;的列表,但您需要确保整个集合再次排序,以便查找实际上有效。

然而,很难知道什么是最适合你的,因为关于你想要达到的目标的信息非常少:数百万的Foo *,数百万的ID *是这个函数经常调用ID *到Foo *?在系统的性能关键部分?所有这些对于代码的可读性,复杂性和性能进行权衡是有用的。