我需要一个满足以下条件的数据结构:
- 存储任意数量的元素,其中每个元素由 10 个数字指标描述
- 允许
log n
通过任何指标快速 ( ) 搜索元素 - 允许快速 (
log n
) 插入新元素 - 允许快速 (
log n
) 移除元素
让我们假设这些元素的构建成本很高。
我想出了以下计划
- 将所有元素存储在一个名为 DATA 的向量中。
- 使用 10
std::sets
,10 个指标中的每一个。每个std:set
都是轻量级的,它只包含整数,它们是向量的索引DATA
。比较运算符在 DATA 中“查找”适当的元素,然后选择适当的度量
template< int C >
struct Cmp
{
bool operator() (int const a, int const b)
{
return ( DATA[a].coords[C] != DATA[b].coords[C] )
? ( DATA[a].coords[C] < DATA[b].coords[C] )
: ( a < b );
}
};
元素永远不会从向量中修改或删除。一个新元素被推回 DATA,然后它的索引 ( DATA.size()-1
) 被插入到集合 ( set<int, Cmp<..> >
) 中。为了删除一个元素,我在元素中设置了一个标志,表示它已被删除(实际上并未将其从DATA
向量中删除),然后从所有十个 std::set 中删除元素索引。
只要DATA
是全局变量,它就可以正常工作。(它还通过使模板化的结构 Cmp 依赖于全局变量而在某种程度上滥用了类型系统。)
但是,我无法将DATA
向量和 std::set 的 ( set<int, Cmp<...> >
) 包含在一个类中,然后将DATA
它们“索引” std::sets
。对于初学者,在外部类中定义的比较运算符 Cmp 无法访问外部类的字段(因此它无法评估 DATA)。我也无法将向量传递给 Cmp 构造函数,因为 Cmp 是由 std::set 构造的,而 std::set 需要一个带有没有参数的构造函数的比较运算符。
我有一种感觉,我正在反对 C++ 类型系统,并试图实现类型系统故意阻止我做的事情。(我试图使 std::set 依赖于仅在运行时构造的变量。)虽然我理解类型系统可能不喜欢我所做的事情,但我认为这是一个合法的用例。
有没有办法实现我上面描述的数据结构/类而不提供 std::set/red-black 树的重新实现?我希望可能有一个我还没有想到的技巧。(是的,我知道 boost 有一些东西,但我想坚持使用标准库。)