calculate the maximum sum of sub-sequence in array

calculate the maximum sum of sub-sequence in array

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <string>
#include <fstream>
#include <sstream>
#include <stdint.h>
#include <pthread.h>
#include <vector>
#include <map>
#include <set>

using namespace std;

void print_array( int* ary,  int len) {
     for ( int i = 0; i < len; ++i) {
         if (0 == i) {
            printf("%3d", ary[i]);
        }  else {
            printf(" %3d", ary[i]);
        }
    }
    printf("\n");
}

int calc_max_sum2( int* ary,  int len) {
     int max_ele = 1 << (8 * sizeof( int) - 1);
     int max_ele_pos = -1;
     int max = 0;

     int sum = 0;
     int start_pos = 0;
     int max_end_pos = -1;
     int max_start_pos = -1;
     for ( int i = 0; i < len; ++i) {
         if (ary[i] > max_ele) {
            max_ele = ary[i];
            max_ele_pos = i;
        }
        sum += ary[i];
         if (sum < 0) {
            sum = 0;
             if (i + 1 < len) {
                start_pos = i + 1;
            }
        }  else  if (sum > max) {
            max = sum;
            max_end_pos = i;
            max_start_pos = start_pos;
        }
    }

     if (max_ele < 0) {
        max = max_ele;
        max_start_pos = max_ele_pos;
        max_end_pos = max_ele_pos;
    }

    printf("algorithm 2: max subsequence starts from %d, length:%d, max result:%d\n", max_start_pos, max_end_pos - max_start_pos + 1, max);
    print_array(ary + max_start_pos, max_end_pos - max_start_pos + 1);

     return max;
}

int calc_max_sum1( int* ary,  int len) {
     if (NULL == ary || 0 == len) {
         return 0;
    }

     int max_ele = 1 << (8 * sizeof( int) - 1);
     int max_ele_pos = -1;

     int max_sum = 0;
     int max_start_pos = -1;
     int max_end_pos = -1;

     int cur_sum = 0;  // reserve the optimal state
     int start_pos = -1;  // record the start pos for cur_sum
     int end_pos = -1; // record the end pos for cur_sum
     int part_sum = 0;  // track the incremental part, and merge into cur_sum once it is positive
     for ( int i = 0; i < len; ++i) {
         if (ary[i] > max_ele) {
            max_ele = ary[i];
            max_ele_pos = i;
        }
        part_sum += ary[i];
         if (part_sum < 0) {
             if (cur_sum + part_sum < 0) {
                 if (cur_sum > max_sum) {
                    max_sum = cur_sum;
                    max_start_pos = start_pos;
                    max_end_pos = end_pos;
                }

                cur_sum = 0;
                start_pos = -1;
                end_pos = -1;
                part_sum = 0;
            }
        }  else  if (part_sum > 0) {
            cur_sum += part_sum;
            part_sum = 0;
            end_pos = i;
             if (-1 == start_pos) {
                start_pos = i;
            }
        }
         // printf("%3d, cur_sum:%3d, start_pos:%3d, end_pos:%3d, part_sum:%3d, max_sum:%3d, max_start_pos:%3d, max_end_pos:%3d\n", i, cur_sum, start_pos, end_pos, part_sum, max_sum, max_start_pos, max_end_pos);
    }
     if (cur_sum > max_sum) {
        max_sum = cur_sum;
        max_start_pos = start_pos;
        max_end_pos = end_pos;
    }

     if (max_ele < 0) {
        max_sum = max_ele;
        max_start_pos = max_ele_pos;
        max_end_pos = max_ele_pos;
    }

    printf("algorithm 1: max subsequence starts from %d, length:%d, max result:%d\n", max_start_pos, max_end_pos - max_start_pos + 1, max_sum);
    print_array(ary + max_start_pos, max_end_pos - max_start_pos + 1);

     return max_sum;
}

int calc_sum( int* ary,  int len) {
     int sum = 0;
     for ( int i = 0; i < len; ++i) {
        sum += ary[i];
    }

     return sum;
}

int calc_max_sum_by_enumerate( int* ary,  int len) {
     int max = 1 << (8 * sizeof( int) - 1);
     int begin = -1;
     int max_len = -1;
     for ( int i = 0; i < len; ++i) {
         for ( int j = i; j < len; ++j) {
             int sum = calc_sum(ary + i, j - i + 1);
             if (sum > max) {
                max = sum;
                begin = i;
                max_len = j - i + 1;
            }
        }
    }

    printf("algorithm of enumerate: max subsequence starts from %d, length:%d, max result:%d\n", begin, max_len, max);
    print_array(ary + begin, max_len);

     return max;
}

int main( int argc,  char* argv[]) {
     int* ary = NULL;
     int len = 0;
     if (argc > 2) {
        len = argc - 1;
        ary =  new  int[len];
         for ( int i = 1; i < argc; ++i) {
            ary[i - 1] = atoi(argv[i]);
        }
    }  else  if (2 == argc) {
        len = atoi(argv[1]);
        ary =  new  int[len];
        struct timeval tv;
        gettimeofday(&tv, NULL);
        srandom(tv.tv_usec);
         for ( int i = 0; i < len; ++i) {
            ary[i] = (random() % 20) - 10;
        }
    }  else {
         int tmp_ary[] = {-4, 6, -5, 3, -3, 4, -2};
        len = sizeof(tmp_ary) / sizeof(tmp_ary[0]);
        ary =  new  int[len];
        memcpy(ary, tmp_ary, sizeof(tmp_ary));
    }
    print_array(ary, len);
     int ret1 = calc_max_sum1(ary, len);
     int ret2 = calc_max_sum2(ary, len);
     int max = calc_max_sum_by_enumerate(ary, len);
     if (ret1 != max) {
        printf("algorithm 1 fails, result is %d, but the right answer is %d\n", ret1, max);
    }  else  if (ret2 != max) {
        printf("algorithm 2 fails, result is %d, but the right answer is %d\n", ret2, max);
    }  else {
        printf("algorithm succeeds, max result:%d\n", max);
    }

    delete [] ary;
     return 0;
}

你可能感兴趣的:(calculate the maximum sum of sub-sequence in array)