求一个数组的最大子数组(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,数组中有正数也有负数,这个数组不是一般的数组,其首 ...
- 求二维数组的最大子数组———曹玉松&&蔡迎盈
继上节课老师让求了一维数组最大的子数组后,这节课堂上,老师加深了难度,给了一个二维数组,求最大子数组,开始觉得很容易,但是自己思考起来感觉这个算法很困难,既需要考虑数组直接的连续,又要求出最大的,老师 ...
随机推荐
- 06.DOM操作应用高级
获取表格tBodies.tHead.tFoot.rows获取行 cells获取td隔行变色 <!DOCTYPE HTML> <html> <head> <m ...
- EXT 下拉框事件
1. <ext:ComboBox ID="cbline" FieldLabel="平台部门来源" runat="server" Dis ...
- 谢欣伦 - OpenDev原创例程 - 时间同步Time Sync
很久以前就发现系统自带的时间同步功能很弱,更新时间总是不成功.索性编写一个小软件来更新系统时间,正好用上了我之前写的代码,相关代码可参见文章<化繁为简系列原创教程 - 通信专题 - 无连接套接字 ...
- CI框架,源代码一次性判断获取post(get)数据是否有某个字段值为空方法
一.以下是CI框架 1.把所有的要接收的字段放在数组中 例: 我要接收:id,name,age,mobile 等字段 $req = array('id','name','age','mobile'); ...
- Android课程---关于数据存储的学习之总结
- .NET中那些所谓的新语法之一:自动属性、隐式类型、命名参数与自动初始化器
开篇:在日常的.NET开发学习中,我们往往会接触到一些较新的语法,它们相对以前的老语法相比,做了很多的改进,简化了很多繁杂的代码格式,也大大减少了我们这些菜鸟码农的代码量.但是,在开心欢乐之余,我们也 ...
- [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序
[.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序 本节导读: 本节主要说明使用异步进行程序设计的优缺点及如何通过异步编程. 使用 ...
- java中文乱码解决之道(三)-----编码详情:伟大的创想---Unicode编码
随着计算机的发展.普及,世界各国为了适应本国的语言和字符都会自己设计一套自己的编码风格,正是由于这种乱,导致存在很多种编码方式,以至于同一个二进制数字可能会被解释成不同的符号.为了解决这种不兼容的问题 ...
- 源文件移动后gdb不显示代码的原因
源文件移动后gdb不显示代码的原因 问题 我们从一个最简单的C语言程序开始.源文件main.c在 用户目录gdb文件夹下. florian@florian-pc:~/gdb$ cat main.c ...
- MySQL Dll语句
标签:MYSQL数据库/DBA/删除数据库表 概述 因为遇到一些事情,从发表上一篇文章到现在中间间隔了好几个月时间:在接下来的时间里会陆续发表关于mysql的一些文章,从基础到优化最后到管理,欢迎关注 ...