软件工程——结对开发环形数组

一、题目:

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

要求:

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

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

如 果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。

同时返回最大子数组的位置。

求所有子数组的和的最大值。要求时间复杂度为O(n)。

二、设计思路

开始想的是用链表实现数组首尾相连,可是由于链表用着不太熟悉,便想了另一种算法:

当最大值未出现跨域是就按常规方法计算找出,

出现跨域时,既然a[0] a[n-1]都出现在解

,则可以将其解延伸到最大,

也就是从a[0]开始,向右扫描,从a[n-1]开始向左扫描,

两者直到出现负数为止, 这样就不会出现中间是负数,但是两端是正数,但却选择整个

序列的情况。

三、源代码

//作者:赵建松、张文冬#include <iostream.h>
#include <stdlib.h>
/*

  * 现在是数组为一个环形结构,最大连续和又该如何实现?

	* 1.最简单的方法:数组循环移位,再进行逐一求解最大连续和,算法复杂度O(n^2)

	  * 2.s[i][l] = s[i][l-1]+a[i+l-1]; sum = max{s[i][l]},s[i][l]:以i开始长度为l的连续和

		* O(n) 的解法:

		  * 1.解未出现跨域的情况,也就是a[0] ~ a[n-1](原问题)

			* 2.解出现跨域情况 a[n-1]~a[0] 出现在解的中间或边界

*/
int max_subarray_bound(int a[],int from,int to)
{
    int i,max,sum;
    max = a[from];
    sum = a[from];
    for(i = from + 1;i <= to;i++)
	{
        if(sum < 0)
		{
            sum = 0;
		}
        sum += a[i];
        if(max < sum)
		{
            max = sum;
		}
    }
    return max;
}
int max_subarray_cycle(int a[],int size)
{
    int sum,i,j,s,m;
    //第一种情况,未跨域
    sum = max_subarray_bound(a,0,size-1);
    /*

	  * 第二种情况,出现跨域,既然a[0] a[n-1]都出现在解中,则可以将其解延伸到最大,

		* 也就是从a[0]开始,向右扫描,从a[n-1]开始向左扫描,两者直到出现负数为止,

		  * 这样就不会出现中间是负数,但是两端是正数,但却选择整个序列的情况.

	*/
	if(size == 2) return sum;
    i = 1;
    j = size-2;
    s = a[i-1] + a[j+1];
    while(i < j && (a[i] >=0 || a[j] >= 0))
	{
        if(a[i] >= 0)
		{
            s += a[i];
            i++;
        }
        if(a[j] >= 0)
		{
            s += a[j];
            j--;
        }
    }
    if(i == j)
	{
        if(a[i] >0) s+=a[i];
        if(s < sum) return sum;
        else return s;
    }
    if(i < j)
	{
        //算出以i为头部的所有连续子数组和或者以j为尾的连续子数组和,从而找到最大的元素
        int s2,k;
        m = a[i];
        s2 = m;
        for(k=i+1;k <= j;k++)
		{
            s2 += a[k];
            if(m < s2)
                m = s2;
        }
        s2 = a[j];
        for(k = j-1;k>=i;k--)
		{
            s2 += a[j];
            if(m < s2)
                m = s2;
        }
        if(m > 0)
			s += m;
    }
    if(s < sum)
		return sum;
    else
		return s;
}
int main(int argc,char *argv[])
{
    int a[] = {5,-3,-1,5,10,11};
	for(int j=0;j<6;j++)
	{
		cout<<a[j]<<" ";
	}
    cout<<endl<<"最大子数组和为:"<<max_subarray_cycle(a,sizeof(a)/sizeof(a[0]))<<endl;
    return 0;
}

  

四、截图

五、体会

在实现环形数组求最大子数组的过程中,我和张文冬分别想了不一样的方法来实现环形数组的问题,但是都存在缺陷和不容易实现的地方,最后找到了这种方法,但由于时间紧迫,功能实现的也不是特别完善,但在讨论各种方法的过程中也发散了我们的思维,有了收获。

时间: 2024-10-12 14:00:27

软件工程——结对开发环形数组的相关文章

结对开发~环形数组篇

实验题目 题目:返回一个整数数组中最大子数组的和. 要求:      输入一个整形数组,数组里有整数也有负数.      数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.      如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],……A[n-1],A[0]……A[j-1]之和最大.      同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 实验思路 由于这次所要求的子数组相当于一个环形的数组,所以就想到了类似数字右循环的形式来解决这个

软件工程课堂训练——结对开发之环数组最大和

一.题目及要求: 题目:返回一个整数数组中最大子数组的和 要求(新加):①如果数组A[0]...A[j-1]首尾相邻,允许A[i-1]...A[n-1],A[0]...A[j-1]之和最大:②同时返回最大子数组的位置. 结对人员:胡亚宝  焦燕 二.设计思路: 我们要解决两个问题:求出环数组中最大的子数组:并且定位出该子数组的位置,把它们的名称输出来.要解决这两个问题,我们从以下两个方面入手: ①求出最大子数组:将数组数值按顺序排好称为“一趟”,每求出一趟的最大子数组后,将第一个数值放到最后一个

结对开发——环形一维数组求最大子数组和

题目:返回一个整数数组中最大子数组的和.要求:(1)输入一个整形数组,数组里有正数也有负数.(2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.(3)如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大.(4)同时返回最大子数组的位置.(5)求所有子数组的和的最大值.要求时间复杂度为O(n).一.设计思想 这个问题的最优解一定是以下两种可能.可能一:最优解没有跨过array[n-1]到array[0],即和非环形数

结对开发——一维数组最大子数组判断溢出

一 题目 求一维数组最大子数组和 要求:1000个数以上,整数 二.设计思路 最大子数组很好找到,但是子数组和的溢出问题很难解决. 经过不断的思考,我得出了结论: 溢出是程程序设计者设计时的不足所带来的错误.所以设计者要在编码时便高度警惕,预防溢出的发生,这才是最本质的解决问题的方法.就本题而言,我们设置了元素最大个数,以及其它输入要求,尽量避免溢出的发生.1000个数相加可以实现,但非要取1000个最大的数相加,那样的计算没有意义,不会在我们的生活学习中出现,这属于科研问题,交给大神们来解决吧

结对开发——循环数组的最大值

一 题目要求: 返回一维数组中最大子数组的和 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值. 要求时间复杂度为O(n) 二 设计思路:(结对思考以及参考于其他同学) 考虑到数组需要首尾相连,采取把数组的长度增加两倍,并把复制的数组写在在最后一个数的后面,这样在循环

软件工程结对开发之求一个数组中连续最大子数组之和

一.团队成员: 檀威,陈志利 二.项目名: 求一个数组中连续最大子数组之和 三.我们的设计思路: 设sum[i]为以第i个元素结尾且和最大的连续子数组.对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且它们之和最大的连续子数组要么是以第i-1个元素结尾且它们之和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] = max(sum[i-1] + arr[i], arr[i]).可以通过判断sum[i-1] + arr[i]是否大于arr[i]来做

3、软件工程结对开发之求一维数组中连续最大子数组之和并判断溢出

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 要求程序必须能处理1000 个元素: 每个元素是int32 类型的: 输入一个整形数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为O(n): 结果溢出之后能判断. 二.设计思想 在我们的前一个程序中,由于int类型rand()随机产生数范围是0~32767,所以产生的1000个数较小,不会产生溢出.但我们通过查资料得知int32最大数是2147

软件工程结对开发之求一个或者多个数组中连续最大子数组之和3

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思想 三.代码 四.截图 五.总结 六.工作合影

软件工程结对开发之求一维数组中连续最大子数组之和2

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 要求程序必须能处理1000 个元素: 每个元素是int32 类型的: 输入一个整形数组,数组里有正数也有负数: 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和: 求所有子数组的和的最大值.要求时间复杂度为O(n): 结果溢出之后能判断. 二.设计思想 在求最大连续子数组时同样用动态法,对于新增的要求,可以增大随机产生数的倍数,如果结果溢出则输出溢出提示字样,其中int类型rand()随机产生数范围是0~32767,i