如何使用独立于其键的比较器函数在find()
上执行lower_bound()
或std::set
函数,使其仍然在O(log N)时间内运行?
假设我使用两个变量foo
和x
定义数据类型y
,并使用std::set<foo>
作为键值。{/ p>
x
是否可以使用struct foo {
int x, y;
foo(int x, int y) : x(x), y(y) {}
};
struct xCompare {
bool operator() (const foo& i, const foo& j) const {
return i.x < j.x;
}
};
// Within main()
std::set<foo, xCompare> fooSetX;
或其他一些比较lower_bound()
值的函数执行二进制搜索?
为了这个论点,假设y
和x
是唯一的并且彼此独立,并且给出了两个y
变量foo
和{{1} },如果foo1
,则foo2
。这意味着我无法将foo1.x < foo2.x
表示为foo1.y < foo2.y
的函数,但y
中的x
也会对其进行排序。
例如,在y
中给出三个fooSetX
值(2,5),(3,9)和(5,10),foo(x,y)
取fooSet
因为搜索项将返回指向(3,9)的迭代器。
目前,我解决此问题的方法是分别按lower_bound()
和y = 7
排序std::set<foo>
两个x
。每当我需要y
搜索时,我都会使用第二个y
。
std::set
答案 0 :(得分:2)
您无法直接将自定义比较器传递给std::set::lower_bound
- 您需要将其传递给类模板本身,因为它将在内部用于维护对象的顺序(从而使std::set::lower_bound
工作)。
以下是std::set
template is defined:
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
Compare
是唯一排序自定义点,允许您提供函数对象,它将根据需要比较您的对象,而不是{{1} }。
无法向std::less<Key>
添加其他排序谓词。
如果您希望在对象上进行额外排序以实现 O(log N)查找,则可以使用与原始查找保持同步的其他有序结构。第一组中使用不同比较器的对象的std::set
指针可以工作。例如:
std::set
答案 1 :(得分:1)
不是std :: set,正如@Vittorio Romeo在答案中指出的那样。
有一个boost datastructure可以由不相关的成员查找,您可以将其定义为
struct foo {
int x, y;
foo(int x, int y) : x(x), y(y) {}
};
// helpers
struct x_tag {};
struct y_tag {};
boost::multi_index_container<
foo,
indexed_by<
ordered_unique<tag<x_tag>, boost::multi_index::member<foo, int, &foo::x>>, // std::less<int> applied to foo::x
ordered_unique<tag<y_tag>, boost::multi_index::member<foo, int, &foo::y>> // std::less<int> applied to foo::y
>
> fooSet;
int an_x, an_y;
// lookup by x
fooSet.get<x_tag>().find(an_x);
fooSet.get<y_tag>().find(an_y);