求一个数组的最大子数组(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,数组中有正数也有负数,这个数组不是一般的数组,其首 ...
- 求二维数组的最大子数组———曹玉松&&蔡迎盈
继上节课老师让求了一维数组最大的子数组后,这节课堂上,老师加深了难度,给了一个二维数组,求最大子数组,开始觉得很容易,但是自己思考起来感觉这个算法很困难,既需要考虑数组直接的连续,又要求出最大的,老师 ...
随机推荐
- ScrollView嵌套RecyclerView时滑动出现的卡顿
原文连接:http://zhanglu0574.blog.163.com/blog/static/113651073201641853532259/ 现象: 一个界面有多个RecyclerView ...
- Unity - Apk包的代码与资源提取
最近在研究如何给Unity游戏进行加密,让别人不能轻易破解你的apk包,不过网上的加密方法都是有对应的破解方法~_~!!结果加密方法没找到好的,逆向工程倒会了不少.今天就来讲解如何提取一个没做任何保护 ...
- .NET各大平台数据列表控件绑定原理及比较(WebForm、Winform、WPF)
说说WebForm: 数据列表控件: WebForm 下的列表绑定控件基本就是GridView.DataList.Repeater:当然还有其它DropDownList.ListBox等. 它们的共同 ...
- TCP/IP, WebSocket 和 MQTT
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的协议.在这三者之间, TCP是HTTP和MQTT底层的协议.大家对HTTP很熟悉,这里简要介绍下MQTT.M ...
- 初识Opserver,StackExchange的监控解决方案
Opserver是闻名遐迩的网站Stack Overflow的开源监控解决方案,由Stack Exchange发布.它基于.NET框架构建,这在监控工具领域有些与众不同. 旨在为每个受监控系统的健康状 ...
- spark 笔记
官网 http://spark.apache.org/ 安装:http://dblab.xmu.edu.cn/blog/spark-quick-start-guide/ 教程 http://www.c ...
- iOS开发系列--UITableView全面解析
--UIKit之UITableView 概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是U ...
- 《Node即学即用》—— 读后总结
导图
- String Aop 动态代理例子
动态代理原理:spring AOP采用动态代理来实现 (1)定义一个接口Boy package aop001; public interface Boy { public void beat(Stri ...
- C# 如何提取SaveFileDialog的保存路径
直接上代码 public TestOne() { InitializeComponent(); SaveFileDialog();//调用打开SaveFileDialog 保存对话框 } #regio ...