分治策略求解子数组最大和并输出下标
2014-08-01 15:58
281 查看
//FindMaxSubarray.h //寻找最大子数组的和,分成三种情况来讨论 /* 在数组A[low...high]中,任何连续子数组A[i...j]的位置有三种 一、完全位于数组A[low...mid]中,因此low<=i<=j<=mid 二、完全位于数组A[mid+1...high]中,因此mid<i<=j<=mid 三、跨越了中点,因此low<=i<=mid<j<=high */ class FindMaxSubarray { public: //寻找跨越中点的数组,得到的是crossLow,crossHigh,crossSum void findMaxCrossingSubarray(int *,int,int,int); //寻找和最大的子数组,得到的是lLow,hHigh,sSum, void findMaxSubarray(int *,int,int); int getLow(){return lLow;} int getHigh(){return hHigh;} int getSum(){return sSum;} private: int leftLow,leftHigh,leftSum; int rightLow,rightHigh,rightSum; int crossLow,crossHigh,crossSum; int lLow,hHigh,sSum; }; void FindMaxSubarray::findMaxCrossingSubarray(int *sPtr,int low,int mid,int high) { int sum=0;//临时子数组和,sum不赋值就蛋疼了!!!!!!!!!! //mid左边的最大和 int left_sum = sPtr[mid];//最接近mid位置的数作为left_sum for(int k=mid;k>=low;k--) { sum = sum + sPtr[k]; if(sum>left_sum)//寻找mid左边最大和 { left_sum = sum; lLow = k; } } int right_sum = sPtr[mid+1];//最接近mid位置的数作为right_sum sum = 0; for(int k=mid+1;k<=high;k++) { sum = sum + sPtr[k]; if(sum>right_sum)//寻找mid右边最大和 { right_sum = sum; hHigh = k; } } //得到跨越mid的字串最大和 sSum = left_sum + right_sum; } void FindMaxSubarray::findMaxSubarray(int * sPtr,int low,int high) { if(low == high)//只有一个元素的起情况 { lLow = low; hHigh = high; sSum = sPtr[low]; } else { int mid = (low+high)/2; findMaxSubarray(sPtr,low,mid);//找出mid左边最大数组和 leftLow = lLow; leftHigh = hHigh; leftSum = sSum; findMaxSubarray(sPtr,mid+1,high);//找出mid右边最大数组和 rightLow = lLow; rightHigh = hHigh; rightSum = sSum; findMaxCrossingSubarray(sPtr,low,mid,high);//找出跨越mid的最大数组和 crossLow = lLow; crossHigh = hHigh; crossSum = sSum; //比较leftSum,rightSum,crossSum的大小来确定sSum if((leftSum>=rightSum)&&(leftSum>=crossSum)) { lLow = leftLow; hHigh = leftHigh; sSum = leftSum; } else if((rightSum>=leftSum)&&(rightSum>=crossSum)) { lLow = rightLow; hHigh = rightHigh; sSum = rightSum; } else { lLow = crossLow; hHigh = crossHigh; sSum = crossSum; } } }
//findMaxSubarray.cpp //寻找最大子数组的和 #include "FindMaxSubarray.h" #define NUMBER 17 #include <iostream> using namespace std; int main() { int testArray[NUMBER+1] = {0,13,-3,-25,-20,-3,-16,23,18,20,-7,12,-5,-22,15,-4,7}; FindMaxSubarray f1; f1.findMaxSubarray(testArray,1,NUMBER); cout << "output the array :" << endl; for(int i=1;i<=NUMBER;i++) cout << " " << testArray[i]; cout << "\nthe max subarray index is " << f1.getLow() << " to " << f1.getHigh() << endl; cout << "the array is :"; for(int i=f1.getLow();i<=f1.getHigh();i++) cout << " " << testArray[i]; cout << "\nmax subarray is : " << f1.getSum(); system("pause >> cout"); return 0; }
下面的是只需要求出子数组最大和,不要求输出下标的程序
<pre name="code" class="cpp">#include <iostream>#define NUMBER 17using namespace std;int findMaxCrossingSubarray(int *,int,int,int);//跨越mid的最大数组和int findMaxSubarray(int *,int,int);int main(){int testArray[NUMBER] = {0,13,-3,-25,-20,-3,-16,23,18,20,-7,12,-5,-22,15,-4,7};cout << "output the array :";for(int i=1;i<NUMBER;i++)cout << " " << testArray[i];cout << "\nthe max subarray sum is :"<< findMaxSubarray(testArray,1,NUMBER-1);system("pause >> cout");return 0;}int findMaxCrossingSubarray(int *sPtr,int low,int mid,int high){int sum=0;int left_sum = sPtr[mid];for(int i=mid;i>=low;i--){sum = sum + sPtr[i];if(sum>left_sum)left_sum = sum;}int right_sum = sPtr[mid+1];sum = 0;for(int k=mid+1;k<=high;k++){sum = sum + sPtr[k];if(sum>right_sum)right_sum = sum;}sum = left_sum + right_sum;return sum;}int findMaxSubarray(int *sPtr,int low,int high){int maxSum;if(low == high)maxSum = sPtr[low];else{int mid = (low+high)/2;int leftSum = findMaxSubarray(sPtr,low,mid);int crossSum = findMaxCrossingSubarray(sPtr,low,mid,high);int rightSum = findMaxSubarray(sPtr,mid+1,high);if(leftSum>=rightSum && leftSum>=crossSum)maxSum = leftSum;else if(rightSum>=leftSum && rightSum>=crossSum)maxSum = rightSum;elsemaxSum = crossSum;}return maxSum;}
相关文章推荐
- 分治策略求解子数组最大并返回下标
- 第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)
- 第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)
- 算法导论:分治策略__最大子数组问题
- 利用for循环和条件运算符输出一个数组中最大和最小值并分别输出下标
- 最大子数组—— Java -分治策略
- 实验 6 数组1输出最大值和它所对应的下标
- 第四章 分治策略 4.1 最大子数组问题(自己想的,不知道是不是减治法)
- 求最大子数组的和,算法导论之分治递归求解,暴力求解,记忆扫描方法。
- 《算法导论》学习笔记——最大子数组(分治策略,动态规划)
- js实现求连续子数组的最大和并输出下标
- 输入n个整数,将它们存入数组a中。输出最大值和它所对应的下标。
- 实验6 数组1 输入n个整数,将它们存入数组a中。输出最大值和它所对应的下标。
- 用递规与分治策略,找出数组中最大元素的位置
- 输入n个整数,将它们存入数组a中。输出最大值和它所对应的下标
- 5-8: 输入一个5行、6列的数组,找出该数组中绝对值最大的元素,输出该元素及其两个下标值
- 实验 6 数组1题目1、输入n个整数,将它们存入数组a中。输出最大值和它所对应的下标
- 数组 (输入n个整数,将它们存入数组a中。输出最大值和它所对应的下标。)
- 分治策略——最大子数组问题
- 求整数数组中最大和子集并输出子集下标