Showing posts with label maximum sub array. Show all posts
Showing posts with label maximum sub array. Show all posts

Saturday, February 2, 2013

Divide and conquer Solution for Maximum Sub Array Problem

Here is C++ code for finding Maximum Sub-Array in a given array using Divide and conquer approach. The program follows the logic given in the book "Introduction to Algorithms".

So what is Maximum Sub Array?
Maximum sub-array is the sub array with largest sum.
For example for the sequence of values −2, 1, −3, 4, −1, 2, 1, −5, 4; the contiguous sub-array with the largest sum is 4, −1, 2, 1, with sum 6.

#include<iostream>
#include<vector>
#include<cstdlib>
#define MINUS_INFINITY -99999

using namespace std;

/*array of elements and its size*/
vector<int> a;
int size;

/*
 * function to find the max sub array in the mid
 */
void max_sub_array_in_mid(int l, int h, int *sum, int *low, int *high) {
    
    int current_sum;
    int l_sum = MINUS_INFINITY;
    int r_sum = MINUS_INFINITY;
    int mid = (l+h)/2;

    current_sum = 0;
    for(int i = mid; i >= l; i--) {
        current_sum += a[i];
        if(current_sum > l_sum)
        {
            l_sum = current_sum;
            *low = i;
        }
    }

    current_sum = 0;
    for(int i = mid+1; i <= h; i++) {
        current_sum += a[i];
        if(current_sum > r_sum) {
            r_sum = current_sum;
            *high = i;
        }
    }

    *sum = l_sum + r_sum;
}

/*
 * This function gets called recursively to find the max sub array 
 * which could be on left/right of mid or the one that is in between
 */
void max_sub_array(int l, int h, int *sum, int *l_index, int *r_index) {
    
    if(l==h) {
        *sum = a[l];
        *l_index = l;
        *r_index = l;
    }
    else {
        int mid = (l+h)/2;
        int l_low,l_high,l_sum;
        int r_low,r_high,r_sum;
        int mid_low,mid_high,mid_sum;

        max_sub_array(l, mid, &l_sum, &l_low, &l_high);
        max_sub_array(mid+1, h, &r_sum, &r_low, &r_high);
        max_sub_array_in_mid(l, h, &mid_sum, &mid_low, &mid_high);
        
        if(l_sum > r_sum && l_sum > mid_sum) {
            *sum = l_sum;
            *l_index = l_low;
            *r_index = l_high;
        }
        else if(r_sum > l_sum && r_sum > mid_sum) {
            *sum = r_sum;
            *l_index = r_low;
            *r_index = r_high;
        }
        else if(mid_sum > r_sum && mid_sum > l_sum) {
            *sum = mid_sum;
            *l_index = mid_low;
            *r_index = mid_high;
        }
    }
}

int main() {
    
    int sum = 0;
    int l_index = -1;
    int r_index = -1;

    cout<<"\nEnter array size\n";
    cin>>size;

    for(int i=0;i<size;i++) {
        //more weightage for negative numbers to generate good test cases
        a.push_back(rand()%100 - rand()%150);
    }
    
    cout<<"\n array is \n";
    for(int i=0;i < size;i++) {
        cout<<a[i]<<" ";
    }
    cout<<endl;

    //Algorithm begins here
    max_sub_array(0, size-1, &sum, &l_index, &r_index);

    cout<<"\n max sub array ranges from "<<l_index<<" to "<<r_index<<endl;
    cout<<"array is:\n";
    for(int i=l_index;i<=r_index;i++)
        cout<<a[i]<<" ";
    cout<<endl;

    return 0;
}