C++ C++;std::使用自定义下界设置
如何在C++ C++;std::使用自定义下界设置,c++,set,stdset,lower-bound,C++,Set,Stdset,Lower Bound,如何在std::set上使用独立于键的比较器函数执行find()或lower_bound()函数,使其仍在O(log N)时间内运行 假设我使用两个变量x和y定义了一个数据类型foo,并使用x作为键值的std::set struct foo { int x, y; foo(int x, int y) : x(x), y(y) {} }; struct xCompare { bool operator() (const foo& i, const foo&
std::set
上使用独立于键的比较器函数执行find()
或lower_bound()
函数,使其仍在O(log N)时间内运行
假设我使用两个变量x
和y
定义了一个数据类型foo
,并使用x
作为键值的std::set
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;
您不能直接将自定义比较器传递给
std::set::lower_bound
——您需要将它传递给类模板本身,因为它将在内部用于维护对象的顺序(从而使std::set::lower_bound
起作用)
以下是
您不能直接将自定义比较器传递给
std::set::lower_bound
——您需要将它传递给类模板本身,因为它将在内部用于维护对象的顺序(从而使std::set::lower_bound
起作用)
以下是
正如@Vittorio Romeo在他的回答中指出的那样,std::set没有 有一个可以由不相关的成员进行查找的
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);
structfoo{
int x,y;
foo(intx,inty):x(x),y(y){}
};
//助手
结构x_标记{};
结构y_标记{};
boost::多索引容器<
福,
索引<
ordered_unique,//std::less应用于foo::x
有序_unique//std::less应用于foo::y
>
>食物;
int an_x,an_y;
//按x查找
fooSet.get().find(an_x);
fooSet.get().find(an_y);
正如@Vittorio Romeo在他的回答中指出的那样,std::set不适用
有一个可以由不相关的成员进行查找的
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);
structfoo{
int x,y;
foo(intx,inty):x(x),y(y){}
};
//助手
结构x_标记{};
结构y_标记{};
boost::多索引容器<
福,
索引<
ordered_unique,//std::less应用于foo::x
有序_unique//std::less应用于foo::y
>
>食物;
int an_x,an_y;
//按x查找
fooSet.get().find(an_x);
fooSet.get().find(an_y);
ooh。所以在我问题中提到的例子中,集合将如何构造(我的意思是实际的代码)?@MuhammadIrhamRasyidi:哎呀,我误解了你的问题-你已经将一个比较器传递给了std::set
。。。嗯,在调用std::set::lower_bound
.Aw时,没有比yCompare
不同的比较器了。我的一个想法是从根到叶手动遍历二叉搜索树,但我不知道怎么做。@MuhammadIrhamRasyidi:您可以简单地迭代(const auto&v:fooSetY){if(v.x==10){/*…*/}
-这对您的用例有效吗?但是,它将在O(N)而不是O(logn)中运行。忘了在问题中提到时间复杂性也是一个问题。所以在我问题中提到的例子中,集合将如何构造(我的意思是实际的代码)?@MuhammadIrhamRasyidi:哎呀,我误解了你的问题-你已经将一个比较器传递给了std::set
。。。嗯,在调用std::set::lower_bound
.Aw时,没有比yCompare
不同的比较器了。我的一个想法是从根到叶手动遍历二叉搜索树,但我不知道怎么做。@MuhammadIrhamRasyidi:您可以简单地迭代(const auto&v:fooSetY){if(v.x==10){/*…*/}
-这对您的用例有效吗?但是,它将在O(N)而不是O(logn)中运行。忘了在问题中提到时间复杂性也是一个问题。
class MySet
{
private:
std::set<Item, Comparator0> _set0;
std::set<decltype(_set0.begin()), Comparator1> _set1;
public:
void insert(Item x)
{
auto res = _set0.insert(x);
assert(res.second);
_set1.insert(res.first);
}
const auto& lookup0(Key0 x) { return _set0.lower_bound(x); }
const auto& lookup1(Key1 x) { return *(_set1.lower_bound(x)); }
};
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);