提问人:Solomon Jacobs 提问时间:8/27/2021 最后编辑:Solomon Jacobs 更新时间:8/27/2021 访问量:93
是否有可能通过 std::upper_bound 对 std::map 进行有效的部分搜索?
Is it possible to do an efficient and partial search of std::map via std::upper_bound?
问:
我有一个和两个键,我计算了 .众所周知,.以下是我目前的做法:std::map
key_small, key_big
upper_bound
key_small <= key_big
#include <map>
#include <algorithm>
int main() {
// Some example data
std::map<int, char> data{{1, 'a'}, {2, 'b'}, {4, 'c'}, {5, 'd'}, {5, 'e'}};
int key_small = 1,
key_big = 3; // key_small <= key_big is always true
auto it_1 = data.upper_bound(key_big);
auto it_2 = data.upper_bound(key_small);
// Do something with it_1, then do something with it_2
}
我想以更有效的方式进行计算。上面的计算没有利用我已经计算过的事实。它第二次搜索整个过程。我试图解决这个问题是做以下事情:it_1
it_2
it_2
it_1
map
auto it_2 = (it_1 == data.end())
? data.upper_bound(key_small)
: std::upper_bound(data.begin(), std::next(it_1), key_small);
第二个调用似乎忽略了底层数据结构。因此,它也是低效的。
有没有更好的计算方法?在我看来,使用比较应该可以找到第二个迭代器。在求职面试中,我被告知这是可能的。it_2
log(std::distance(data.begin(), it_1)
我不在乎该解决方案是否仅在 c++20 中可用。我也接受特定于 libstdc++ 或 libc++ 的解决方案。如果该解决方案也适用于该解决方案,那就太好了。find
答:
0赞
eerorika
8/27/2021
#1
是否有可能通过 std::upper_bound 对 std::map 进行有效的部分搜索?
虽然可以与非随机访问迭代器一起使用,但它与这些迭代器具有线性复杂性。所以,是的,这是可能的,但这种线性搜索是否有效取决于具体情况,在最坏的情况下,它会比两次查找慢。std::upper_bound
std::map::upper_bound
如果 ,那么它可能更有效。distance(it_1, it_2) < log2(N)
有没有办法让两种计算it_2方式都受益?
该接口不提供此类算法。我不认为任何算法的最坏情况会比两个查找更好。
评论
0赞
eerorika
8/27/2021
@NathanOliver嗯,我想我想错了。
0赞
Solomon Jacobs
8/27/2021
好吧,这似乎是正确的答案,但我仍然希望有人可以解释,为什么界面不提供这样的算法。也许这是不可能的,因为黑红树的工作方式?
0赞
eerorika
8/27/2021
@SolomonJacobs 关于计算机科学的问题在于,要回答这个问题是极其困难的:“已知的算法是最优的,还是存在更好的算法”。除非你首先证明存在更好的算法,否则问为什么没有使用这种算法的接口是没有意义的。
0赞
user2407038
8/27/2021
“渐近更好的最坏情况”——事实上,渐近行为是相同的,但 OP 正在寻找的这种算法肯定比一个常数因素更快。
评论
it_1
it_2