[英]Is it possible to do an efficient and partial search of std::map via std::upper_bound?
I have a std::map
and two keys key_small, key_big
for which I compute the upper_bound
.我有一个
std::map
和两个键key_small, key_big
我计算upper_bound
。 It is known that key_small <= key_big
.已知
key_small <= key_big
。 Here is how I currently do it:这是我目前的做法:
#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
}
I would like to compute it_1
and it_2
in a more efficient manner.我想以更有效的方式计算
it_1
和it_2
。 The computation of it_2
above does not take advantage of the fact that I have computed it_1
already.上面
it_2
的计算没有利用我已经计算it_1
的事实。 It searches the whole map
a second time.它第二次搜索整个
map
。 My attempt to remedy this is to do the following:我试图解决这个问题是做以下事情:
auto it_2 = (it_1 == data.end())
? data.upper_bound(key_small)
: std::upper_bound(data.begin(), std::next(it_1), key_small);
The second call seems to ignore the underlying data structure.第二次调用似乎忽略了底层数据结构。 Thus, it is also inefficient.
因此,它也是低效的。
Is there a better way of computing it_2
?有没有更好的计算
it_2
的方法? It appears to me that finding the second iterator should be possible using log(std::distance(data.begin(), it_1)
comparisons. I was told it's possible in a job interview.在我看来,使用
log(std::distance(data.begin(), it_1)
比较应该可以找到第二个迭代器。在工作面试中有人告诉我这是可能的。
I don't care if the solution is only available in c++20.我不在乎该解决方案是否仅在 c++20 中可用。 I also accept solutions specific to libstdc++ or libc++.
我也接受特定于 libstdc++ 或 libc++ 的解决方案。 It would be nice if the solution worked with
find
as well.如果该解决方案也适用于
find
,那就太好了。
Is it possible to do an efficient and partial search of std::map via std::upper_bound?
是否可以通过 std::upper_bound 对 std::map 进行高效的部分搜索?
Although std::upper_bound
can be used with non-random access iterators, it has linear complexity with those iterators.尽管
std::upper_bound
可以与非随机访问迭代器一起使用,但它与那些迭代器具有线性复杂度。 So, yes it is possible to do it but whether such linear search is efficient depends on the particular case, and in worst case it will be slower than two std::map::upper_bound
lookups.所以,是的,可以这样做,但这种线性搜索是否有效取决于特定情况,在最坏的情况下,它会比两次
std::map::upper_bound
查找慢。
If distance(it_1, it_2) < log2(N)
, then it may be more efficient.如果
distance(it_1, it_2) < log2(N)
,那么它可能更有效率。
Is there a way to reap the benefits for both ways of computing it_2?
有没有办法从两种计算 it_2 的方式中获益?
The interface doesn't provide such algorithm.该接口不提供此类算法。 I don't think that any algorithm could have asymptotically better worst case than the two lookups.
我认为没有任何算法可以比这两个查找渐近地更好地处理最坏情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.