gpt4 book ai didi

c++ - 为什么 std::binary_search 的参数是前向迭代器?

转载 作者:IT老高 更新时间:2023-10-28 22:02:52 26 4
gpt4 key购买 nike

在阅读 http://en.cppreference.com/w/cpp/algorithm/binary_search 时我注意到它将转发迭代器作为参数。现在我很困惑,因为我认为它宁愿是一个随机访问迭代器,所以二进制搜索实际上是二进制的。

为了满足我的好奇心,我写了一个小程序:

#include <iostream>
#include <vector>
#include <forward_list>
#include <list>
#include <deque>
#include <algorithm>
#include <chrono>
#include <random>

int main()
{
std::uniform_int_distribution<int> uintdistr(-4000000, 4000000);
std::mt19937 twister(std::chrono::high_resolution_clock::to_time_t(std::chrono::high_resolution_clock::now()));
size_t arr[] = { 200000, 400000, 800000, 1600000, 3200000, 6400000, 12800000 };
for(auto size : arr)
{
std::list<int> my_list;
for(size_t i = 0; i < size; i++)
my_list.push_front(uintdistr(twister));
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
my_list.sort(); //fixed
start = std::chrono::high_resolution_clock::now();

std::binary_search(my_list.begin(), my_list.end(), 1252525);

end = std::chrono::high_resolution_clock::now();
long long unsigned elapsed_time = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
std::cout << "Test finished in " << elapsed_time << "\n";
}
}

用 gcc 4.7.0 编译并运行

g++ -std=c++11 test.cpp

在我的机器上提供以下结果:

Test finished in 0
Test finished in 15625
Test finished in 15625
Test finished in 46875
Test finished in 93750
Test finished in 171875
Test finished in 312500

所以看起来它实际上并没有在前向列表上进行二进制搜索。现在我的问题是:

为什么会有这样一个令人困惑的名字?

为什么允许这样的代码?

为什么引用文献说它是“第一个和最后一个之间距离的对数”?

标准对此有何规定?

编辑:现在代码在搜索之前对列表进行排序 - 愚蠢的错误,现在结果是:

Test finished in 46875
Test finished in 109375
Test finished in 265625
Test finished in 546875
Test finished in 1156250
Test finished in 2625000
Test finished in 6375000

当然仍然不是对数;)

最佳答案

原始 SGI STL 实现的文档,该标准源自该文档,states that

The number of comparisons is logarithmic: at most log(last - first) + 2. If ForwardIterator is a Random Access Iterator then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to last - first.

也就是说,比较次数总是对数,而由于缺乏随机可访问性而影响的进步次数可以是线性的。在实践中,stl::advance可能使用,如果迭代器是随机访问,则复杂度是恒定的,否则是线性的。

如果比较非常昂贵,则具有线性数量的迭代器改进但具有对数比较数的二进制搜索是有意义的。例如,如果您有一个复杂对象的排序链表,需要磁盘或网络访问才能进行比较,那么使用二分搜索可能比使用线性搜索要好得多。

关于c++ - 为什么 std::binary_search 的参数是前向迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13502128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com