// L-22 MCS 360 Wed 13 Oct 2010 : binary_search_in_vector.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;

vector<int> generate ( int n );
// generates a vector of n random elements

void write ( vector<int> v );
// writes the entire vector v

void write ( vector<int> v, int a, int b );
// writes the vector v from a to b (bounds include)

int search ( vector<int> v, int a, int b, int e );
// returns k, with a <= k <= b if v[k] == e,
// otherwise returns -1

int main()
{
   cout << "give n : ";
   int n; cin >> n;

   vector<int> v = generate(n);
   cout << "v : "; write(v); cout << endl;
   sort(v.begin(),v.end());
   cout << "v : "; write(v); cout << endl;

   cout << "give a number : ";
   int e; cin >> e;

   int k = search(v,0,v.size()-1,e);
   if(k == -1)
      cout << e << " does not occur in v" << endl;
   else
      cout << e << " = v[" << k << "] = " << v[k] << endl;

   // using STL algorithms :

   cout << "Does " << e << " occur ? ";
   bool answer = binary_search(v.begin(),v.end(),e);
   string s = (answer) ? "yes" : "no";
   cout << s << endl;

   // lower bound returns first position where e can be inserted
   // while maintaining the sorted order

   vector<int>::iterator i;
   i = lower_bound(v.begin(),v.end(),e);
   int d = i - v.begin();
   if(v[d] == e)
      cout << e << " occurs at v[" << d << "]" << endl;
   else
      cout << e << " does not occur in v" << endl;

   return 0;
}

vector<int> generate ( int n )
{ 
   srand(time(0));

   vector<int> v;
 
   for(int i=0; i<n; i++)
      v.push_back(rand() % 100);

   return v;
}

void write ( vector<int> v )
{
   for(int i=0; i < v.size(); i++) 
      cout << " " << v[i];
}

void write ( vector<int> v, int a, int b )
{
   for(int i=a; i <= b; i++) 
      cout << " " << v[i];
}

int search ( vector<int> v, int a, int b, int e )
{
   if(a == b)
      return (v[a] == e) ? a : -1;
   else
   {
      int m = (a+b)/2;
      cout << "m = " << m;
      if(v[m] == e)
      {
         cout << " found " << e << endl;
         return m;
      }
      else if(v[m] < e)
      {
         cout << " search in";
         write(v,m+1,b); cout << endl;
         return search(v,m+1,b,e);
      }
      else
      {
         cout << " search in";
         write(v,a,m-1); cout << endl;
         return search(v,a,m-1,e);
      }
   }
}

