我正在研究迭代器,并且已经停留了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;
请帮忙。
答案 0 :(得分:4)
这样做是为了避免在添加两个非常大的整数时可能发生的溢出,其中加法结果可能变得大于最大整数限制并产生奇怪的结果。
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;
答案 1 :(得分:3)
二进制搜索传统上是这样编写的。这种写作形式有助于编码人员理解二进制搜索,因为在标准二进制搜索中只使用了开始,结束,中间。
你 可以1>}而不是size()
在循环之前,但你必须使用end-star
循环,因为end-start
会改变。您应该避免使用end-start
来保持一致性。