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

Is it possible to do an efficient and partial search of std::map via std::upper_bound?

提问人:Solomon Jacobs 提问时间:8/27/2021 最后编辑:Solomon Jacobs 更新时间:8/27/2021 访问量:93

问:

我有一个和两个键,我计算了 .众所周知,.以下是我目前的做法:std::mapkey_small, key_bigupper_boundkey_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_1it_2it_2it_1map

auto it_2 = (it_1 == data.end())
                    ? data.upper_bound(key_small)
                    : std::upper_bound(data.begin(), std::next(it_1), key_small);

第二个调用似乎忽略了底层数据结构。因此,它也是低效的。

有没有更好的计算方法?在我看来,使用比较应该可以找到第二个迭代器。在求职面试中,我被告知这是可能的。it_2log(std::distance(data.begin(), it_1)

我不在乎该解决方案是否仅在 c++20 中可用。我也接受特定于 libstdc++ 或 libc++ 的解决方案。如果该解决方案也适用于该解决方案,那就太好了。find

C++ 字典 查找 std

评论

2赞 Vlad from Moscow 8/27/2021
目前尚不清楚您要查找的内容。
0赞 WilliamClements 8/27/2021
听起来您想进行一次调用,指定多个键,并为每个键获取生成的上限迭代器。也许实现可以做出更聪明的猜测,而不是它对 n 个单独的二进制(尽管逐渐变小)搜索所做的。
0赞 Solomon Jacobs 8/27/2021
@WilliamClements 是的,这是我的想法,但我不知道如何实现它。
0赞 Solomon Jacobs 8/27/2021
来自莫斯科的@Vlad 你能具体说明哪个部分不清楚吗?我只是在尝试进行计算和,但以更有效的方式。it_1it_2
0赞 Vlad from Moscow 8/27/2021
@SolomonJacobs 更新前的代码片段没有意义。

答:

0赞 eerorika 8/27/2021 #1

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

虽然可以与非随机访问迭代器一起使用,但它与这些迭代器具有线性复杂性。所以,是的,这是可能的,但这种线性搜索是否有效取决于具体情况,在最坏的情况下,它会比两次查找慢。std::upper_boundstd::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 正在寻找的这种算法肯定比一个常数因素更快。