要求
1,输入一个整型数组,数组里有正数也有负数。
2,数组中连续的一个或多个整数组组成一个子数组,每个子数组都有一个和。
3,如果数组A[0].......A[j-1]首尾相邻,允许A[i-1],.........A[n-1],A[0],.........A[j-1]之和最大。
4,同时返回最大子数组的位置。
5,求所有子数组的和的最大值。
设计思路
1,
很容易理解,当我们加上一个正数时,和会增加,当我们加上一个负数时,和合减少,如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零。
不然的话这个负数将会减小接下来的和,这是延续上次一维整数数组最大子数组和的思路。
2,
调用随机函数rand(),srand()生成随机数组。
3,
因为数组的首尾元素相连,所以我们可以想象成一个圆环。设想从圆环的任意一个位置切一刀不就又形象的成为一维数组首尾不相连的情况了吗,所以,考虑的这个因素,
我们通过在数组后面重新添加前n-1个元素,实现数组的循环机制(注意此处添加的是前n-1个,而非n个。)
源代码
1 #include<iostream> 2 #include<time.h> 3 #include<stdlib.h> 4 using namespace std; 5 int MaxSum(int data[],int length,int &start,int &end) 6 { 7 int max=data[0]; 8 int starttemp=0,endtemp=0;//定义开始和结束位置 9 int cursum=0;//定义元素和 10 if(data==NULL||length<0) 11 { 12 return 0; 13 }//数组为空的处理 14 for(int i=0;i<length;i++) 15 { 16 if(cursum<=0)//数组元素和小于零时,重置为第i个元素 17 { 18 cursum=data[i]; 19 starttemp=i; 20 endtemp=i; 21 } 22 else 23 { 24 cursum+=data[i];//数组元素大于零时,累加 25 endtemp=i; 26 } 27 if(cursum>max)//当前和大于最大和,则重置最大和 28 { 29 max=cursum; 30 start=starttemp;//子数组元素开始及结束位置 31 end=endtemp; 32 } 33 } 34 return max; 35 } 36 int main() 37 { 38 int n; 39 cout << "Number of elements in array:" << endl; 40 cin >> n; 41 srand((unsigned)time(NULL));//实现不同随机数的生成 42 int data[2*n-1]; 43 { 44 for(int j=0;j<n;j++) 45 { 46 data[j]=rand()%21-10; 47 cout << data[j] << " "; 48 } 49 for(int j=0;j<(n-1);j++) 50 { 51 data[n+j]=data[j]; 52 }//输出-10到10的n个随机数 53 } 54 int length=sizeof(data)/sizeof(int);//数组长度计算 55 int start=0,end=0; 56 int result=MaxSum(data,length,start,end);//调用函数 57 cout << endl; 58 cout<<"MaxOfSubarrays="<<endl; 59 for(int i=start;i<=end;i++) 60 cout<<data[i]<<" ";//输出最大子数组 61 cout<<endl; 62 cout<<"MaxSumOfSubarrays="<<" "<<endl; 63 cout<<result<<endl;//输出最大子数组的和 64 return 0; 65 }
运行截图
总结
在这次的编程之中也遇到过一些因代码书写错误等造成的编译错误,但都一一调试解决了。
因为有了之前一维数组求最大子数组的经验,这次的实验,在之前的基础上操作,在明确了设计思路,有了编程解决问题的想法之后,显得简单了不少。
感觉这次的编程题目主要是这种解决问题的思路值得借鉴。
小组成员
20163957 于芳娜
20163952 张素颖