求一个数组的最大子数组(C/C++实现)
最大子数组:要求相连,加起来的和最大的子数组就是一个数组的最大子数组。编译环境:VS2012,顺便说句其实我是C#程序员,我只是喜欢学C++。
其实这是个半成品,还有些BUG在里面,不过总体的思路是这样的,求最大的子数组,由一个中位分开,就是数组的中间位置,然后分别求中间位置横跨的,左边的,和右边的最大的,然后比较三者的大小,最大的为最大子数组。思路来自算法导论。今天算是把伪代码都实现了,但是貌似有点BUG,不知道有大神帮我提一下不?为了节约时间,我索性把一些问题的解释放过来,是算法导论的,我也是看的这本书做的。




本人声明,这次是我自己写的代码,下面的,我没有看别人写的,主要还是想锻炼下自己,结合上面的算法导论看基本上就没什么问题了,晚安。
// ConsoleApplication8.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream> using namespace std;
template <class T> int getArrayLen(T& array) //使用模板定义一个函数getArrayLen,该函数将返回数组array的长度 { return (sizeof(array) / sizeof(array[0])); } int _tmain(int argc, _TCHAR* argv[])
{
void findMaxSubArray(int [],int); int a[]={5,-100,34535,32,10,5,4,-100,2}; //初始化数组
int len=getArrayLen(a);
findMaxSubArray(a,len);
system("pause"); return 0;
} void findMaxSubArray(int a[],int len)
{
//声明
int getSubArraysPreIterator(int [],int ,int,int );
int getSubArrayMid(int ,int ,int ,int [],int ); //低位下标
int low=0;
//高位下标
int high=0;
//中间位数
int mid=0; //最大子数组
int sum=0; //第一种情况下
int sumAfter=0; //第二种情况下
int sumMid=0; //第三种情况下
int mid_RightPos=0; //横跨中间数组的右边界
int mid_LeftPos=0; //横跨中间的数组的左边界 int sumMidFromRight=0; //从右边开始计算 int arrLen=len;//数组长度 //如果数组中只有一个元素
if(arrLen==1)
{
cout<<" 最大子数组是:"<<a[0]<<endl;
} mid=arrLen/2; //算出中间的位置 /*有3种可能的情况
1.最大子数组在中位数的左边
2.最大子数组在中位数的右边
3.最大子数组横跨中间*/ //先求第一种情况
for(int i=mid;i>=0;i--)
{
sum=sum+a[i];
int sum_=getSubArraysPreIterator(a,mid,i,0);
if(sum<sum_)
{
sum=getSubArraysPreIterator(a,mid,i,0);
low=i; //最大子数组左边的边界。
} }
cout<<"最大子数组(左)是:"<<sum<<endl;
cout<<"low:"<<low<<endl; //第二种情况
for(int i=mid+1;i<arrLen;i++)
{
sumAfter=sumAfter+a[i];
int sum_After=getSubArraysPreIterator(a,mid,i,1);
if(sumAfter<sum_After)
{
sumAfter=getSubArraysPreIterator(a,mid,i,1);
high=i;
} //如果没进入上面的IF语句,则表示是最后一个
if(high==0&&i==arrLen-1)
{
high=i;
}
} cout<<"最大子数组(右)是:"<<sumAfter<<endl;
cout<<"high:"<<high<<endl; //确定了最低位的下标和最高位的下标,下面进行跨中位运算
for(int i=low+1;i<high;i++)
{
sumMid=sumMid+a[i]; //从LOW开始考虑问题
int sumMid_=getSubArrayMid(low,high,i,a,0); if(sumMid<sumMid_)
{
sumMid=getSubArrayMid(low,high,i,a,0);
mid_RightPos=i;
} //从HIGH开始考虑问题
int sumMid_High=getSubArrayMid(low,high,i,a,1); if(sumMid<sumMid_High)
{
sumMidFromRight=getSubArrayMid(low,high,i,a,1);
mid_LeftPos=i;
} //比较大小
if(sumMid<sumMidFromRight)
{
sumMid=sumMidFromRight;
mid_RightPos=mid_LeftPos;
} }
cout<<"横跨中间的子数组是:"<<sumMid<<endl;
cout<<"横跨中间的数组的右边界是:"+mid_RightPos<<endl; //比较三个求出来的值的大小,确定谁才是最大子数组。
if(sum>sumAfter)
{
if(sum>sumMid)
{
cout<<"最终结果:"<<sum<<"为最大子数组"<<endl;
}
else
{
cout<<"最终结果:"<<sumMid<<"为最大子数组"<<endl;
} }
else
{
if(sum<sumMid)
{
if(sumMid>sumAfter)
{
cout<<"最终结果:"<<sumMid<<"为最大子数组"<<endl;
}
else
{
cout<<"最终结果:"<<sumAfter<<"为最大子数组"<<endl;
}
} } } //根据下标获得子数组(前一次迭代的和的结果)
int getSubArraysPreIterator(int a[],int mid,int i,int flag)
{
//获得要求的子数组的跨度
int span=mid-i; //总和
int sum=0; //左边
if(flag==0)
{
//计算前一次元素的和,以和上面的后一次的函数所得到的和做笔记
for(int k=mid;k>=i+1;k--)
{
sum+=a[k];
}
return sum; } //右边
if(flag ==1)
{
for(int k=mid+1;k<i;k++)
{
sum+=a[k]; }
return sum;
} } //获得子数组(跨中线)
//注意:因为从中线可能是从中线的左边,或者是右边的数组是最大子数组,所以要区别对待 int getSubArrayMid(int low,int high,int i,int a[],int flag)
{
int sum=0; if(flag==0)
{
for(int k=low+1;k<i;k++)
{
sum+=a[k];
}
return sum;
}
else if(flag==1)
{
for(int k=high-1;k>i;k--)
{
sum+=a[k];
}
return sum; } }
求一个数组的最大子数组(C/C++实现)的更多相关文章
- 求解数组环中最大子数组和的问题(java)
//石家庄铁道大学 信1405-1 班 唐炳辉 在上一次作业中,对于普通数组的最大子数组的求解问题的基础上,将普通的数组变成一个首尾相接的环,求这个环的最大子数组.类似的,只要改变普通数组的数组位置, ...
- 软件工程结对开发——返回一个整数数组中最大子数组的和(JAVA)
题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整型数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为 ...
- Task 4.3 求环形数组的最大子数组和
任务要求:输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n- ...
- 蚂蚁的难题(二)首尾相连数组的最大子数组和(DP)
蚂蚁的难题(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 下雨了,下雨了,蚂蚁搬家了. 已知有n种食材需要搬走,这些食材从1到n依次排成了一个圈.小蚂蚁对每种食材 ...
- nyoj 983 ——首尾相连数组的最大子数组和——————【最大子串和变形】
首尾相连数组的最大子数组和 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首 ...
- nyoj--983--首尾相连数组的最大子数组和(动态规划)
首尾相连数组的最大子数组和 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是 ...
- nyoj983 首尾相连数组的最大子数组和
首尾相连数组的最大子数组和 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是 ...
- NYOJ 745 首尾相连数组的最大子数组和
首尾相连数组的最大子数组和 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首 ...
- 求二维数组的最大子数组———曹玉松&&蔡迎盈
继上节课老师让求了一维数组最大的子数组后,这节课堂上,老师加深了难度,给了一个二维数组,求最大子数组,开始觉得很容易,但是自己思考起来感觉这个算法很困难,既需要考虑数组直接的连续,又要求出最大的,老师 ...
随机推荐
- 20145337 GDB调试汇编堆栈过程分析
20145337 GDB调试汇编堆栈过程分析 测试代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const ...
- 大家一起Aop
一.前言 1.在项目中无处不充斥着记录日志的代码,各种try catch,实在是有点看着不爽.这不,果断要想法子偷个懒儿. 二.摘要 鄙人不才,先总结一下个人想到的可实现AOP的几种思路: 1.通过继 ...
- 对改善ABP的一些建议
园子里有不少同学对ABP框架很感兴趣,而且也已经将ABP用在了商用项目中,有些可能还在操练阶段.一般来说,我们使用ABP默认的一些功能已经足够了,但还是有很多人想要自己拓展一些功能而自己实现不了或者说 ...
- js中几种实用的跨域方法原理详解
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- Mac 软件篇
对于美好事务的追求无论何时都不算晚. ** 文章内容来着我整理的fetool,以下内容可能更新不及时 ** Mac 下的软件那么多,又是免费又是付费,应该怎么选呢?我来分享下我的推荐列表,推荐的优先级 ...
- Step by Step 配置使用HTTPS的ASP.NET Web应用
原创地址:http://www.cnblogs.com/jfzhu/p/4064654.html 转载请注明出处 有关HTTPS.SSL以及SSL证书的工作原理,参见 <HTTPS那些事(一)H ...
- PHP fsockopen 异步调用接口在nginx上偶尔实效的情况
private function fsock_asy_do($get){ $fp = fsockopen("ssl://www.xxx.com", 443, $errno, $er ...
- Apache-Tomcat的安装配置
现在将使用Tomcat的一些经验和心得写到这里,作为记录和备忘.如果有朋友看到,也请不吝赐教. 1.首先是Tomcat的获取和安装. 获取当然得上Apache的官方网站下载,开源免费,而且带宽也足够. ...
- Oracle 创建普通用户,并赋予权限
采用sys or system / manager as sysdba; 连接数据库. 创建普通用户konglin: create user konglin identified by pwd_ora ...
- SQL Server 解读【已分区索引的特殊指导原则】(3) - 非聚集索引分区
一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...