C ++ std :: set with custom lower_bound

时间:2017-03-17 11:42:02

标签: c++ set stdset lower-bound

如何使用独立于其键的比较器函数在find()上执行lower_bound()std::set函数,使其仍然在O(log N)时间内运行?

假设我使用两个变量foox定义数据类型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()值的函数执行二进制搜索?

为了这个论点,假设yx是唯一的并且彼此独立,并且给出了两个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

2 个答案:

答案 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);