最大連續子數組

最大連續子數組:

 

  1. 暴力求解最大連續子數組

 

代碼:

#include <iostream>

#include <cstdio>

using namespace std;

 

int main()

{

   int A[8] = { -6, 10, -5, -3, -7, -1, -1 };

   int array_length = sizeof(A) / sizeof(A[0]);//數組大小

   int sum = -10000;//記錄子數組的和

   int low;//記錄子數組的底

   int height;//記錄子數組的高

   for (int i = 0; i < array_length; i++)

    {

       for (int j = i ; j < array_length; j++)

       {

           int subarraysum=0;//所遍歷出來的子數組的和

           //計算遍歷的子數組之和

           for (int k = i; k <= j; k++)

           {

                subarraysum += A[k];

           }

           //找出最大的子數組

           if (subarraysum>sum)

           {

                sum = subarraysum;

                low = i;

                height = j;

           }

       }

    }

   printf("%d  %d  %d\n", low, height,sum);//將結果打印出來

   getchar();

 

   return 0;

}

 

2.分治法(算法導論)

 

代碼:

#include <limits.h>

#include <stdio.h>

struct PSum{

   int low;

   int high;

   int sum;

};

 

 

//跨越中點的最大子數組,這是最特殊也是最好的找的一段區間

PSum FIND_MAX_CROSSING_SUBARRAY(int *A ,int low , int mid , int high)

{

   int i;

   int sum=0;

   int right_sum=INT_MIN,left_sum=INT_MIN;

   int max_left=0,max_right=0;

 

//先找左邊最大的,再找右邊最大的,直接暴力找就好了

   for(i=mid ; i>=low ; i--){

       sum+=A[i];

       if(sum>left_sum){

           left_sum=sum;

           max_left=i;

       }

    }

 

   sum=0;

   for(i=mid+1 ; i<=high ; i++){

       sum+=A[i];

       if(sum>right_sum){

           right_sum=sum;

           max_right=i;

       }

    }

 

   PSum ps;

   ps.low = max_left;

    ps.high= max_right;

   ps.sum = left_sum + right_sum;

   return ps;

}

//還是遞歸的思想,全部都交給中間段來找,如何進行比較大小

PSum FIND_MAXIMUM_SUBARRAY(int *A , int low, int high)

{

   if (low == high)

    {

       PSum ps;

       ps.low = low;

       ps.high = high;

       ps.sum = A[low];

       return ps;

    }

   else{

       int mid = (low + high) / 2;

       PSum left = FIND_MAXIMUM_SUBARRAY(A, low, mid);

       PSum right = FIND_MAXIMUM_SUBARRAY(A, mid + 1, high);

       PSum cross = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high);

       if (left.sum >= cross.sum && left.sum >= right.sum){

           return left;

       }

       else if (right.sum >= left.sum && right.sum >= cross.sum){

           return right;

       }else{

           return cross;

       }

    }

 

}

 

int main()

{

   int A[8] = {-6, 10, -5, -3, -7, -1, -1};

   PSum result;

   result = FIND_MAXIMUM_SUBARRAY(A, 0, 7);

   printf("%d %d %d\n", result.low , result.high , result.sum);//將結果打印出來

   //getchar();

   return 0;

}

 

 

 

 

 

3.在線算法

 

代碼:

//在線法求最大子數組和問題

int  main()

{

    int A[8] = { -6, 10, -5, -3, -7, -1, -1 };

    int array_length = sizeof(A) /sizeof(A[0]);//數組大小

    int sum = 0;//記錄子數組的和

    int thisSum = 0;

    for (int i = 0; i < array_length; i++)

    {

        thisSum += A[i];

        if (thisSum > sum){

            sum = thisSum;

        }

//如果累加和出現小於0的情況, 

//則和最大的子序列肯定不可能包含前面的元素, 

//這時將累加和置0,從下個元素重新開始累加

        else if (thisSum < 0) {

            thisSum = 0;

        }

    }

printf("%d",sum);//將結果打印出來

return 0;

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章