最大子数组和(首尾相连)

最大子数组和(首尾相接)

一:题目

返回一个一维整数数组中最大子数组的和。

二:要求

输入一个一维整形数组,数组里有正数也有负数。

一维数组首尾相接,像个一条首尾相接带子一样。

数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

求所有子数组的和的最大值。

三:设计思路

整体思路(主要是基于最大子数组和一):

         首先,生成任意个整数数组,有正有负;其次,分别将一串数的每一个数作为第一数(后面的跟上,前面的按照顺序跟在最后)放在临时数组中;然后对每一组这样的临时数组,选出其中的最大值,放在临时结果数组中;最后,对最后临时结果数组进行遍历,找出最大的结果。

详细:

         (此处,语言不太好表达,举出一个例子)

         (若初始数组为1,2,-3

那么临时数组1为:1,2,-3;存入临时结果数组为:3,0;最终临时结果数组为:3;

(若为负,临时数组长度加一,保留初始化的值0)

临时数组2为:2,-3,1;存入临时结果数组为:2,0,1;最终临时结果数组为:2;

临时数组3为:-3,1,2;存入临时结果数组为:0,1,2;最终临时结果数组为:2;

最后,最终临时为3,2,2,遍历这个数组找最大值为3。)

四:源程序代码

//最大子数组的和(相邻且首尾相连)
//20143066毛雯雯,2016.4.11
#include<iostream>
#include<cstdlib>
#include <new> 
#include<ctime>
#define N 100
using namespace std;
int main()
{
	int i;//循环变量
	srand(unsigned(time(0)));
	
	int num;
	num = rand()%10+1;//随机数的个数
	cout<<"产生一个有"<<num <<"个数的数组"<<endl;

	int *initial;//初始数组
	initial= new  int[num]; //动态申请空间
	
	int r;//random,随机确定正数或负数
	for(i=0;i<num;i++)//初始数组的赋值
	{
		r = rand()%2;
		if(r==1)
		{
			initial[i] = rand()%100+1;
		}
		if(r==0)
		{
			initial[i] = 0 - (rand()%100+1);
		}
	}

	cout<< "产生的数组为: " <<endl;
	for(i=0;i<num;i++)//初始数组的显示,用来检查
	{
		cout<<initial[i]<<"  ";
	}
	cout << endl;

	int middle[N*N],result[N*N];//middle数组是存放一次循环的结果的,result数组是放一次循环后的最大的值的
	int j ;
	int k;
	int q;
	int s;
	int *temp;
	temp= new  int[num];//temp数组临时存放数组——把初始数组的每一个分别看成第一个
	

	for(i=0;i<N*N;i++)//初始化
	{
		middle[i]=0;
		result[i]=0;
	}
	
	for(k=0;k<num;k++)//把每个数当作第一个
	{
		for(i=0;i<num-k;i++)
		{
			temp[i]=initial[i+k];
		}
		if(k!=0)
		{
			s=0;
			for(i=num-k;i<num;i++)
			{
				if(s<k)
				{
					temp[i]=initial[s];
					s++;
				}
			}
		}
		//临时数组显示
		cout<<k+1<< ":临时数组为:" << endl;
		for(i=0;i<num;i++)
		{
			cout<<temp[i]<<" ";
		}
		cout << endl;

		j=0;
		for(i=0;i<num;i++)
		{
			if(temp[i]>0)
			{
				middle[j]=temp[i]+middle[j];
			}
			else
			{
				j++;	
			}
		}
		result[k]=middle[0];
		cout<<"临时存放最大子数组和为: "<<endl;
		for(i=0;i<j+1;i++)
		{
			cout << middle[i] << "  ";
			if(middle[i]>result[k])
			{
				result[k] = middle[i];
			}
		}
		cout << endl;
		for(i=0;i<N*N;i++)
		{
			middle[i]=0;
		}
	}

	int final=result[0];
	for(i=0;i<num;i++)//得最后的结果
	{
		if(final<result[i])
		{
			final = result[i];
		}
	}
	if(final==0)
		cout<<"为负数数组,不计算"<<endl;
	else
		cout << "最大子数组的和为:" << final;

	delete[ ] initial; //释放动态申请空间
	delete[ ] temp; 
}

  

五:结果截图

 

六:体会

这次做这道题花的时间有点久,一是,自己也有点乱,分不清哪个是哪个数组,后来就不用简单的一个字母作为数组名了;二是,自己的思路在脑子里想的,实际并不完整,后来还是在纸上做了分析,才做出来,并且出错的时候,也是根据纸上的重新过了一遍,才找到错误。

七:缺陷

使用随机数生成数组,会出现全负的情况,针对这个问题,我只在显示的时候做了处理(若全负,则显示“计算不了”),没有在数组生成后进行处理。

八:收获

以前都不写设计思路,上来就建文件什么的,这几次下来,越来越发现设计思路的重要性了,以后要培养这个好习惯!

原文地址:https://www.cnblogs.com/justmaomao/p/5388202.html