Ronzii's Blog

Just your average geek's blog

Ceiling and Floor Search

#include <iostream>
using namespace std;
int ceilSearch(int a[], int low, int high, int x)
{
    if(x<a[low]) return low;
    if(x>a[high]) return -1;
    int mid = (low+high)/2;
    if(a[mid]==x) return mid;
    /* If x is smaller than arr[mid], then either arr[mid]
    is ceiling of x or ceiling lies in arr[mid-1...high] */
    else if(x<a[mid])
    {
        if(x>=a[mid-1])
            return mid;
        else
            ceilSearch(a,low,mid-1,x);

    }
    /* If x is greater than arr[mid], then either arr[mid + 1]
        is ceiling of x or ceiling lies in arr[mid+1...high] */
    else
    {
        if(x<=a[mid+1])
            return mid+1;
        else
            ceilSearch(a,mid+1,high,x);

    }
}
int floorSearch(int a[], int low, int high, int x)
{
    if(x<a[low]) return -1;
    if(x>a[high]) return high;
    int mid = (low+high)/2;
    if(x==a[mid]) return mid;
    else if(x<a[mid])
    {
        if(x>=a[mid-1])
            return mid-1;
        else
            floorSearch(a,low,mid-1,x);
    }
    else
    {
        if(x<=a[mid+1])
            return mid;
        else
            floorSearch(a,mid+1,high,x);
    }
}
int main()
{
    int arr[] = {1, 2, 8, 10, 10, 12, 19};
    int n = sizeof(arr)/sizeof(arr[0]);
    int x,index;
    while(1)
    {
        cin>>x;
        index = ceilSearch(arr, 0, n-1, x);
        if(index == -1)
            cout<<"Ceiling of "<<x<<" doesn't exist in array \n";
        else
            cout<<"Ceiling of "<<x<<" is "<<arr[index]<<endl;
        index = floorSearch(arr, 0, n-1, x);
        if(index == -1)
            cout<<"Floor of "<<x<<" doesn't exist in array \n";
        else
            cout<<"Floor of "<<x<<" is "<<arr[index]<<endl;

    }
    return 0;
}

March 30, 2012 Posted by | C++ | , , , , | Leave a comment

Binary Search in a Matrix

This algorithm uses divide and conquer to divide the matrix into two parts. This algorithm has an average complexity of o((logn)^2). Therefore, it performs better than step wise search from a corner(O(m+n)).

  1. Let us assume we are searching for target. 
  2. Find i,j along the middle column(j) such that a[i][j]<target<a[i+1][j] using binary search.
  3. Divide into 2 parts along this co-ordinate
#include <iostream>
#define MAX 5
using namespace std;
//  T(n) = 2T(n/2) + c lg n
// Column Partition
bool binaryPartition(int a[][MAX],int r, int c, int R, int C, int target)
{
    if(c>C || r>R) return false;
    if(target<a[r][c] || target>a[R][C]) return false;
    int mid = c + (C-c)/2;
    int row = r;
    // Binary search position where a[i] < target < a[i+1]
    while(row<=R && a[row][mid]<=target)
    {
        if(a[row][mid]==target) return true;
        row++;
    }
    // Divide into 2 parts
    return binaryPartition(a,row,c,R,mid-1,target) || binaryPartition(a,r,mid+1,row-1,C,target);
}
bool binaryPartition(int a[][MAX], int M, int N, int target)
{
    return binaryPartition(a,0,0,M-1,N-1,target);
}
int main()
{
    int a[MAX][MAX] = {{1,4,7,11,15},{2,5,8,12,19},{3,6,9,16,22},{10,13,14,17,24},{18,21,23,26,30}};
    int count = 0;
    for(int i=0; i<MAX; i++)
    {
        for(int j=0; j<MAX; j++)
        {
            count+=binaryPartition(a,MAX,MAX,a[i][j]);
        }
    }
    if(count==MAX*MAX)
    {
        cout<<"All Found";
    }
    return 0;
}

March 27, 2012 Posted by | C++ | , , , | Leave a comment

Count the number of occurrences in a sorted array

Algorithm
  1. Use Binary search to get index of the first occurrence of x in arr[] (i)
  2. Use Binary search to get index of the last occurrence of x in arr[] (j)
  3. Return (j – i + 1)
#include <iostream>
using namespace std;
int lower_bound(int a[],int low,int high, int x)
{
    if(low<=high)
    {
        int mid = (low+high)/2;
        if(a[mid]==x && (a[mid-1]<x || mid==0)) return mid;
        if(x<a[mid])
            return lower_bound(a,low,mid-1,x);
        else
            return lower_bound(a,mid+1,high,x);
    }
    return -1;
}
int upper_bound(int a[],int low,int high, int x, int n)
{
    if(low<=high)
    {
        int mid = (low+high)/2;
        if(a[mid]==x && (a[mid+1]>x || mid==n-1)) return mid;
        if(x<a[mid])
            return upper_bound(a,low,mid-1,x,n);
        else
            return upper_bound(a,mid+1,high,x,n);
    }
    return -1;
}
int count(int a[],int n,int x)
{
    int i = lower_bound(a,0,n-1,x);
    if(i==-1) return 0;
    int j = upper_bound(a,0,n-1,x,n-1);
    return j-i+1;
}
int main()
{
    int a[] = {1,1,1,40,40,40,110};
    int n = sizeof(a)/sizeof(a[0]);
    cout<<count(a,n,40)<<endl;
    return 0;
}

March 26, 2012 Posted by | C++ | , , , , | Leave a comment