最大子数组:要求相连,加起来的和最大的子数组就是一个数组的最大子数组。编译环境: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. Javascript中call和apply的区别和用法

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别.其实就是更改对象的内部指针,即改变对象的this指向的内容.这在面向对象的js编程过程中有时是很有用的.call ...

  2. MYSQL删除重复数据

     delete from co_jobinformation cwhere c.name in (select cc.name from co_jobinformation cc group by   ...

  3. ASP.net之策略模式

    设计思路: 用ASP.net设计,调用策略模式.在第一个数和第二个数的文本框中输入数值,单击录题按钮,数值保存在n1,n2文档中,把要做的题都保存完后,单击开始按钮,开始做题,做完单击判断按钮,进行判 ...

  4. 使用java反射机制编写Student类并保存

    定义Student类 package org; public class Student { private String _name = null; ; ; public Student() { } ...

  5. 使用jQuery.form插件,实现完美的表单异步提交

    传送门:异步编程系列目录…… 时间真快,转眼一个月快结束了,一个月没写博客了!手开始生了,怎么开始呢…… 示例下载:使用jQuery.form插件,实现完美的表单异步提交.rar 月份的尾巴,今天的主 ...

  6. jQuery.Callbacks之demo

    jQuery.Callbacks是jquery在1.7版本之后加入的,是从1.6版中的_Deferred对象中抽离的,主要用来进行函数队列的add.remove.fire.lock等操作,并提供onc ...

  7. [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

    [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...

  8. JAVA基础-输入输出:1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。

    1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上. package Test03; ...

  9. MongoDB 内嵌文档

    MongoDB是文档型的数据库系统,doc是MongoDB的数据单位,每个doc相当于关系型数据库的数据行(row),doc和row的区别在于field的原子性:row中的column是不和分割的原子 ...

  10. 移动端web开发

    meta基础知识点: 页面自动调整到设备宽度,并禁止用户缩放. <meta name="viewport" content="width=device-width, ...