我有一组n
个对象。每个对象都有2个数字属性A
和B
。
我知道A
和B
上的订单完全相关:obj1.A > obj2.A
当且仅当obj1.B > obj2.B
。
如果我将集合实现为按A
排序的集合,
我可以在O(log n)
中支持以下操作:
A
但在属性std::lower_bound
上搜索B
将是线性的,因为集合不支持RandomAccessIterators。
我知道我可以定义自己的二叉树实现(例如:红黑或AVL),它将在每个节点中存储A
和B
值。通过这种方式,我可以为所有4个操作O(log n)
。
是否有更简单(更高级别)的方法来有效支持4个操作(搜索属性,插入和删除)?
答案 0 :(得分:1)
我在评论中絮絮叨叨的一个例子:
#include <set>
#include <iostream>
namespace test {
struct test {
int A;
int B;
};
bool operator< (test const& lhs, test const& rhs) {
return lhs.A < rhs.A;
}
struct test_B { double B; };
bool operator< (test const& lhs, test_B const& rhs) {
return lhs.B < rhs.B;
}
bool operator< (test_B const& lhs, test const& rhs) {
return lhs.B < rhs.B;
}
}
int main() {
std::set<test::test, std::less<void>> example {
{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}
};
std::cout << example.lower_bound<test::test_B>({3.5})->B;
return 0;
}
c ++ 14允许集合在可以与其密钥进行比较的任何内容上调用lower_bound
。现在,我所做的只是创建一个与我的原始结构相当的包装类型,但它会查看B
值。实际上,我set::lower_bound
默认B
而不是A
。
由于你的数字键是相关的,我怀疑你会得到lower_bound
的承诺集合性能。
您可以查看here
答案 1 :(得分:1)
我建议使用boost multi-index在容器中包含多个索引。