最大子数组:要求相连,加起来的和最大的子数组就是一个数组的最大子数组。编译环境: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++实现)的更多相关文章

  1. 求解数组环中最大子数组和的问题(java)

    //石家庄铁道大学 信1405-1 班 唐炳辉 在上一次作业中,对于普通数组的最大子数组的求解问题的基础上,将普通的数组变成一个首尾相接的环,求这个环的最大子数组.类似的,只要改变普通数组的数组位置, ...

  2. 软件工程结对开发——返回一个整数数组中最大子数组的和(JAVA)

    题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整型数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为 ...

  3. Task 4.3 求环形数组的最大子数组和

    任务要求:输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.    如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n- ...

  4. 蚂蚁的难题(二)首尾相连数组的最大子数组和(DP)

    蚂蚁的难题(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 下雨了,下雨了,蚂蚁搬家了. 已知有n种食材需要搬走,这些食材从1到n依次排成了一个圈.小蚂蚁对每种食材 ...

  5. nyoj 983 ——首尾相连数组的最大子数组和——————【最大子串和变形】

    首尾相连数组的最大子数组和 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首 ...

  6. nyoj--983--首尾相连数组的最大子数组和(动态规划)

    首尾相连数组的最大子数组和 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是 ...

  7. nyoj983 首尾相连数组的最大子数组和

    首尾相连数组的最大子数组和 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是 ...

  8. NYOJ 745 首尾相连数组的最大子数组和

    首尾相连数组的最大子数组和 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首 ...

  9. 求二维数组的最大子数组———曹玉松&&蔡迎盈

    继上节课老师让求了一维数组最大的子数组后,这节课堂上,老师加深了难度,给了一个二维数组,求最大子数组,开始觉得很容易,但是自己思考起来感觉这个算法很困难,既需要考虑数组直接的连续,又要求出最大的,老师 ...

随机推荐

  1. ajax post提交form表单 报400错误 解决方法

    昨天晚上做项目遇到了一个奇怪的问题,我用ajax提交一个form表单,后台Java方法用的是一个实体接,但是他根本不进方法体中,直接给我一个400的错误,一开始我以为是我路径的问题(尴尬),结果直接访 ...

  2. js 模版加载到前端

    js 模版加载到前端 简单有效不高端 配个路由 /js/:filename ,  用 readTemplate 响应请求,前端可以按模块方式直接 require 模板 'use strict' var ...

  3. “眉毛导航”——SiteMapPath控件的使用(ASP.NET)

    今天做网站的时候,用到了SiteMapPath控件,我把使用方法记录下来,以便日后查阅以及帮助新手朋友们. SiteMapPath”会显示一个导航路径(也称为痕迹导航或眉毛导航),此路径为用户显示当前 ...

  4. 5.Powershell变量

    在指令执行过程中,会有一些数据产生,这些数据被用于以后的语句,需要一个存储单元暂时的存放这些数据,这个时候定义一个变量来存储数据.例如$string = “Hello Powershell!” Pow ...

  5. 基于OWin的Web服务器Katana发布版本3

    当 ASP.NET 首次在 2002 年发布时,时代有所不同. 那时,Internet 仍处于起步阶段,大约有 5.69 亿用户,每个用户平均每天访问 Internet 的时间为 46 分钟,大约有 ...

  6. 剑指Offer面试题:11.打印1到最大的n位数

    一.题目:打印1到最大的n位数 题目:输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数即999. 二.不同的解法 2.1 不假思索的解法 最容易想到的办 ...

  7. .Net组件程序设计之对象生命周期

    .Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是 ...

  8. [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决

    这篇文章主要讲述Python如何安装Numpy.Scipy.Matlotlib.Scikit-learn等库的过程及遇到的问题解决方法.最近安装这个真是一把泪啊,各种不兼容问题和报错,希望文章对你有所 ...

  9. mysql导入导出sql文件

    window下 1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u dbuser -p dbname > dbname.sql2. ...

  10. HTML5的实用

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC"; color: #ffffff } p.p2 ...