简体   繁体   English

是否可以通过 std::upper_bound 对 std::map 进行高效的部分搜索?

[英]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_1it_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM