Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

to find the middle item in a vector, why use "mid = beg + (end - beg) / 2" instead of " mid = (beg + end) /2"

Tags:

c++

vector

I'm new to C++. I saw this code online, where it is trying to find a string within a vector. However, I have noticed right towards the end:

mid = beg + (end - beg) / 2;

Why does it have to be written in this way, why can't it be written as:

mid = (beg + end) /2

Is mid = (beg + (end - 1)) / 2 a feasible alternative?

I'm struggling to understand the reason behind it.

vector<string> text = {"apple", "beer", "cat", "dog"};
    string sought = "beer";

    auto beg = text.begin(), end = text.end();
    auto mid = text.begin() + (end - beg) / 2;
    while (mid != end && *mid != sought){
        if(sought < *mid){
            end = mid;
        } else {
            beg = mid + 1;
        }
        mid = beg + (end - beg) / 2;
    }
like image 978
Thor Avatar asked Feb 16 '16 01:02

Thor


2 Answers

In general with binary search, the reason is to avoid overflow. beg+end is subject to overflow with large values. Using end-beg avoids the overflow.

Imagine of beg was MAX_INT-3 and end was MAX_INT-1, then beg+end would be larger than MAX_INT, but end-beg, would just be 2.

With iterators, this also works out because end-begin is a number, whereas begin+end is not valid. You can subtract two iterators to get the distance between them, but you can't add two iterators.

like image 66
Vaughn Cato Avatar answered Nov 20 '22 12:11

Vaughn Cato


Adding two iterators doesn't make sense, and you can't do that.

You can call operator- on two iterators, and gives a reasonable result, i.e. the count of elements between two iterators. And you can add or subtract an integral number on iterator, means move it forward or backward. But what should be the result of adding two iterators?

mid = beg + (end - beg) / 2;
             ~~~~~~~~~~      => get the count between beg and end
            ~~~~~~~~~~~~~~~  => get the half of the count
      ~~~~~~~~~~~~~~~~~~~~~  => get the iterator pointing to the middle position between beg and end

mid = (beg + end) /2
       ~~~~~~~~~  => What would the result represent?
like image 4
songyuanyao Avatar answered Nov 20 '22 10:11

songyuanyao