c++ - 使用迭代器进行二进制搜索,为什么我们使用 "(end - begin)/2"?

标签 c++ algorithm iterator binary-search

<分区>

我正在研究迭代器,并在弄清楚我们为什么使用迭代器上卡住了 3 天:

auto mid = text.begin() + (end - beg) / 2;

代码:

int main()

{
    vector<int> text{ 10,9,8,7,6,5,4,3,2,1 };
    int sought = 3;
    // text must be sorted
    // beg and end will denote the range we're searching
    auto beg = text.begin(), end = text.end();
    auto mid = text.begin() + (end - beg) / 2; // original midpoint
                                               // while there are still elements to look at and we haven't yet found sought
    while (mid != end && *mid != sought) {
        if (sought < *mid) // is the element we want in the first half?
            end = mid; // if so, adjust the range to ignore the second half
        else // the element we want is in the second half
            beg = mid + 1; // start looking with the element just after mid
        mid = beg + (end - beg) / 2;// new midpoint
    }

    system("pause");
}

为什么

auto mid = text.begin() + (end - beg) / 2;

而不是:

auto mid = text.begin() + text.size() / 2;

请帮忙。

最佳答案

这样做是为了避免在将两个非常大的整数相加时可能发生溢出,在这种情况下相加结果可能会变得大于最大整数限制并产生奇怪的结果。

Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken

来自博客:

So what's the best way to fix the bug? Here's one way:
 6:             int mid = low + ((high - low) / 2);

Probably faster, and arguably as clear is:
 6:             int mid = (low + high) >>> 1;

In C and C++ (where you don't have the >>> operator), you can do this:
 6:             mid = ((unsigned int)low + (unsigned int)high)) >> 1;

关于c++ - 使用迭代器进行二进制搜索,为什么我们使用 "(end - begin)/2"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38560566/

相关文章:

c++ - 在 C++ 中将秒数转换为 UNIX 时间戳

c++ - 如何默认构造迭代器的value_type作为函数中的默认参数?

c++ - 生成一组检查消息内容的方法

c++ - 内存动态分配 C++ 性能改进

Java计算器 - 调车场

c++ - mantin wep 在 C++ 中的实现

algorithm - 使用 Fisher-Yates shuffle 从链表中获取 k 个随机值

javascript - 为什么迭代 Set 的值会分配并产生垃圾?

c++ - 我在 map 中有 9 个元素,但 begin() 和 end() 之间的距离只有 2

c++ - MSVC6 如何处理来自 extern "C"函数的异常?