最大子序列和详解
来源:互联网 发布:农村淘宝的现状分析 编辑:程序博客网 时间:2024/06/05 11:46
最大子序列和详解
在求解最大子序列和时可以使用多种不同的方法 其中对于分治思想:将一个n规模的问题分为2个n/2规模的问题,再将问题的解做简单合并。其中n/2规模的问题可以继续分开处理。对于最大子序列和最大值存在3种情况1在左边2在右边3跨越中间,如果跨越中间将左侧最左部分一直相加到右侧最右部分即可判断。
详细代码如下:
void test(){ // int array[] = {4 , -3, 5, 2, -1, 2, 8, -2, 100}; int array[] = {-4 , -3, 5, 2, -1, 2, 8, -2, -100}; // int array[] = {-4 , -3, 5, 2, -1, 2, 8, -2, -100, 3}; // int array[] = {-4 , -3, 5, 2, -1, 2, 8, -2, -100, 300}; // int array[] = {-1, 2, 3, -3}; // int array[] = {-1, 2}; findSequence(array, sizeof(array)/sizeof(int)); findSequenceOptimize(array, sizeof(array)/sizeof(int)); findSequencePosition(array, sizeof(array)/sizeof(int)); findSequencePositionOptimize(array, sizeof(array)/sizeof(int)); int result = deleaveSequenceSum(array, sizeof(array)/sizeof(int)); NSLog(@"the result is %d", result); int a = 0; int b = 0; result = deleaveSequenceSumRecursionByjeffasd(array, sizeof(array)/sizeof(int), &a, &b); NSLog(@"the result is %d", result);}void findSequence(int arr[], int length){ static int calculateCount = 0; int maxSum = 0; for (int i = 0; i < length; i++) { int sequeueSum = arr[i]; for (int j = i + 1; j < length; j++) { sequeueSum += arr[j]; if (sequeueSum > maxSum) { maxSum = sequeueSum; } printf("calculate count is %d\n", calculateCount++); } } printf("maxSum is %d\n", maxSum);}/** 最优算法 */void findSequenceOptimize(int arr[], int length){ int maxSum = 0; int sequeueSum = 0; for (int i = 0; i < length; i++) { sequeueSum += arr[i]; if (sequeueSum > maxSum) { maxSum = sequeueSum; }else if (sequeueSum < 0){ sequeueSum = 0;//重点是这个 当序列和小于0时将序列和置为0 } } printf("maxSum is %d", maxSum);}/** 最大子序列和带子序列的位置计算 */void findSequencePosition(int arr[], int length){ int maxSum = 0; int start = 0; int end = 0; for (int i = 0; i < length; i++) { int sequeueSum = 0; for (int j = i; j < length; j++) { sequeueSum += arr[j]; if (sequeueSum > maxSum) { maxSum = sequeueSum; end = j; start = i; } } } for (int i = start; i <= end; i++) { int temp = arr[i]; printf("sequence value position %d is %d\n", i, temp); } printf("maxSum is %d\n", maxSum);}/** 带位置计算最优算法 */void findSequencePositionOptimize(int arr[], int length){ int maxSum = 0; int sequeueSum = 0; int start = 0; int end = 0; BOOL startIsInNext = YES; for (int i = 0; i < length; i++) { sequeueSum += arr[i]; if (sequeueSum > maxSum) { maxSum = sequeueSum; end = i; if (startIsInNext == YES) { start = i; startIsInNext = NO; } }else if (sequeueSum < 0){ sequeueSum = 0;//重点是这个 当序列和小于0时将序列和置为0 if (i != length - 1) { startIsInNext = YES; } } } for (int i = start; i <= end; i++) { int temp = arr[i]; printf("sequence value position %d is %d\n", i, temp); } printf("maxSum is %d", maxSum);}#define _in#define _out#define _inoutint findSequencePositionByDeleave(int arr[], int length, _out int * startP, _out int * endP){ int maxSum = 0; // *startP = 0; // *endP = 0; for (int i = 0; i < length; i++) { int sequeueSum = 0; for (int j = i; j < length; j++) { sequeueSum += arr[j]; if (sequeueSum > maxSum) { maxSum = sequeueSum; *endP = j; *startP = i; } } } for (int i = *startP; i <= *endP; i++) { int temp = arr[i]; printf("sequence value position %d is %d\n", i, temp); } // //左侧 // int mid = length/2; //左侧 0-mid //右侧 mid+1 - length //1.值全部在左侧 //2.值全部在右侧 //3.值跨越左侧和右侧 printf("maxSum is %d\n", maxSum); return maxSum;}/** 将问题分成两部分再分别处理 伪分治算法 */int deleaveSequenceSum(_in int arr[], _in int length){ //左侧 int mid = length/2; int leftStart = 0; int rightEnd = 0; int leftSum = 0; int rightSum = 0; int tempSum = 0; int tempLeftStart = 0; leftSum = findSequencePositionByDeleave(arr, mid, &leftStart, &rightEnd); rightSum = findSequencePositionByDeleave(&arr[mid], length - (mid), &tempLeftStart, &rightEnd); rightEnd = rightEnd + mid; for (int i = leftStart; i <= rightEnd; i++) { tempSum += arr[i]; printf("sequence value tempSum %d is %d\n", i, tempSum); } int leftRightMax = leftSum > rightSum ? leftSum : rightSum; if (tempSum > leftRightMax ) { return tempSum; }else{ return leftRightMax; }}//首先找到问题的最小规模 最小规模的计算要和 非最小规模的计算分开 非最小规模可以将问题拆分成两个或更多个相同或相似的子问题,再把子问题分成更小的子问题 再将多个子问题的和做合并//分治递归解决问题int deleaveSequenceSumRecursionByjeffasd(_in int arr[], _in int length, _out int * startP, _out int * endP){ //问题的最小规模 - 当length为2时还可以再次细分 static int calculateCount = 0; printf("calculate count is %d\n", calculateCount++); if (length <= 1) { //起点和重点都是 0 *startP = 0; *endP = 0; return arr[0]; }else{ //左侧 int mid = length/2; int leftStart = 0; int rightEnd = 0; int leftStartTemp = 0; int rightEndTemp = 0; int leftSum = 0; int rightSum = 0; int tempSum = 0; leftSum = deleaveSequenceSumRecursionByjeffasd(arr, mid, &leftStart, &rightEndTemp);//计算左侧 起点 此处不关心 右侧结束点 rightSum = deleaveSequenceSumRecursionByjeffasd(&arr[mid], length - (mid), &leftStartTemp, &rightEnd);//计算右侧 结束点 此处不关心 左侧起点 leftStartTemp = leftStartTemp + mid; rightEnd = rightEnd + mid; for (int i = leftStart; i <= rightEnd; i++) { tempSum += arr[i]; printf("sequence value tempSum %d is %d\n", i, tempSum); } int leftRightMax = leftSum > rightSum ? leftSum : rightSum; if (tempSum > leftRightMax ) { *startP = leftStart; *endP = rightEnd; return tempSum; }else{ if (leftSum > rightSum) { *startP = leftStart; *endP = rightEndTemp; }else{ *startP = leftStartTemp; *endP = rightEnd; } return leftRightMax; } }}
阅读全文
0 0
- 最大子序列和详解
- 最大子序列和
- 最大子序列和
- 最大和子序列
- 最大子序列和
- 最大子序列和
- 最大子序列和
- 最大子序列和
- 最大子序列和?
- 最大子序列和
- 最大子序列和
- 和最大子序列
- 最大子序列和
- 最大子序列和
- 最大子序列和
- 最大子序列和
- 最大子序列和
- 最大和子序列
- [乐意黎原创] CentOS7.2里apche配置SSL及抛SSLProtocol: Protocol 'TLSv1.1' overrides already... 解决方法
- oracle创建自增字段
- Material Design之CollapsingToolbarLayout使用(折叠式标题栏)
- 多人部件解析--Towards Real World Human Parsing: Multiple-Human Parsing in the Wild
- PHP命名空间详解。
- 最大子序列和详解
- php遍历路径文件
- 【官方解说】Visual Studio 2017(VS 2017)各个版本有什么区别
- 文章标题
- Java 习题4 答案及解析
- PhP功能模块扩展——ImageMagick
- C++ Primer Plus(第六版)—— 第四章 复合类型 笔记和答案
- RR报文解析(二) fraction lost
- Material Design之TabLayout的用法(标题栏滑动+ViewPager)