Maximum sub-array, divide and conquer, and brute force Solution
A Simple Algorithm for Finding the largest sum of consecutive subarrays is written. The time complexity of the enumeration method is nlgn, and the violent law is n ^ 2. However, when n is relatively small, the violence law is more effective and it is always curious about the extent to which it is small, so I wrote a program test.
First look at the brute force Solution
Int FindMaxSubArrayViolently (int a [], int high, int & p, int & q) // high is array a without subscript, p and q use the application type to save the start subscript and the last small mark {int sum_max =-INFINITE, sum; for (int I = 0; I
Divide and conquer Law
Idea: subarrays must be one of the three situations:
1. In the Sub-array a [low... mid]
2. In a [mid + 1... high]
3. Crossing the midpoint
The first two good solutions, the array a [low... high] binary, recursion to return when low> = high, a [low] is the maximum continuous sub-array. If there is only one continuous sub-array, this is the maximum continuous sub-array ). The third method is to obtain the maximum continuous sub-array of the left and right sides of the mid point and then add them together. The Code is as follows:
int FindMaxSubArray(int a[],int low,int high,int &p,int &q){ if (low==high) { p=q=low; return a[low]; } else { int mid=(low+high)/2,left_low,left_high,left_sum,right_low,right_high,right_sum,cross_low,cross_high,cross_sum; left_sum=FindMaxSubArray(a,low,mid,left_low,left_high); right_sum=FindMaxSubArray(a,mid+1,high,right_low,right_high); cross_sum=FindMaxCrossingSubArray(a,low,high,cross_low,cross_high); if(left_sum>=right_sum && left_sum>=cross_sum) { p=left_low;q=left_high; return left_sum; } else if(right_sum>=left_sum && right_sum>=cross_sum) { p=right_low;q=right_high; return right_sum; } else { p=cross_low;q=cross_high; return cross_sum; } }}
When crossing a point:
int FindMaxCrossingSubArray(int a[],int low,int high,int &p,int &q){ int sum_left,sum_right,sum=0,i,max_left,max_right,mid=(low+high)/2; sum_left=sum_right=-INFINITE; for(i=mid,sum=a[mid];i>=low;sum+=a[--i]) if(sum>sum_left) { sum_left=sum; max_left=i; } for(i=mid+1,sum=a[i];i<=high;sum+=a[++i]) if(sum>sum_right) { sum_right=sum; max_right=i; } p=max_left;q=max_right; return sum_left+sum_right;}
Next, write a random number generator to generate test data:
void GenerateRandNum(int a[],int n){ srand(n); for(int i=0;i<n;i++) a[i]=-rand()%2000+1000;}
Next, call the windows api to test the time:
int main(){ DWORD start,end,t1,t2; int a[MAXN],low,high,sum,n=10; t1=t2=0; while(n<MAXN && t2>=t1) { GenerateRandNum(a,n); start=GetTickCount(); sum=FindMaxSubArrayViolently(a,n-1,low,high); end=GetTickCount(); t1=end-start;/*----------------------------------------------------------------*/ GenerateRandNum(a,n); start=GetTickCount(); sum=FindMaxSubArray(a,0,n-1,low,high); end=GetTickCount(); t2=end-start; n+=10; } printf("%d",n); return 0;}
The test result is smaller than I think, about n is in the range of 400 ~ The effect of the division and Control Law between 500 is better than that of the violence law.
This article is from the "Casablanca" blog, please be sure to keep this source http://vinttwade.blog.51cto.com/7772448/1277330