一、程序题目
返回一个整数数组中最大子数组的和。
二、程序要求
1、输入一个整数数组,数组中有正数也有负数。
2、数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
3、如果数组A[0].......A[j-1]首尾相邻,允许A[i-1],......A[n-1],A[0].......A[j-1]之和最大。
4、同时返回最大子数组的位置。
5、求所有子数组的和的最大值。
三、程序设计思想
这次最大的问题是需要判断始末位置。可以形成一个固定长度的窗口,依次相加比较。首先将为两种情况,一种是跨越a[n-1],a[0]的。一种是没有跨越的。对于没有跨越的,方法很多。对于跨零点的,则可以转换成求其子数组最小和。由于数组总和确定。对于中间那段必定为最小和。总和减最小和求出最大和。对于两个最大和进行比较。得到最终结果。
四、源程序代码
1 //李俏、张莹荧,2016.3.26 2 //求整数数组的最大子数组的和,数组可循环 3 4 #include<iostream> 5 #include<stdlib.h> 6 #include <time.h> 7 using namespace std; 8 struct ret 9 { 10 int max, start, end; //用于存放最大值,及始末位置 11 }; 12 13 struct ret max2(int arry[], int length) //跨越arry[n-1]、arry[0]的最大和 14 { 15 int total = 0; 16 int start1 = 0; 17 int start2; //起始位置 18 int end = 0; 19 int sum = arry[0]; 20 int minsum = arry[0]; 21 for (int i = 1; i<length; i++) 22 { 23 if (sum>0) 24 { 25 sum = arry[i]; 26 start1 = i; 27 } 28 else 29 { 30 sum = sum + arry[i]; 31 32 } 33 if (minsum >= sum) 34 { 35 minsum = sum; 36 end = i; 37 start2 = start1; 38 } 39 total = total + arry[i]; 40 } 41 total = total + arry[0]; 42 minsum = total - minsum; 43 struct ret ret1 = { minsum, start2, end }; 44 return ret1; 45 } 46 47 struct ret max1(int arry[], int length) //不跨越零点的最大和 48 { 49 int start1 = 0; 50 int start2; //起始位置 51 int end = 0; 52 int sum = arry[0]; 53 int maxsum = arry[0]; 54 for (int i = 1; i<length; i++) //求出相邻数组最小和 55 { 56 if (sum<0) 57 { 58 sum = arry[i]; 59 start1 = i; 60 } 61 else 62 { 63 sum = sum + arry[i]; 64 } 65 if (maxsum <= sum) 66 { 67 start2 = start1; 68 end = i; 69 maxsum = sum; 70 } 71 } 72 struct ret ret1 = { maxsum, start2, end }; 73 return ret1; 74 } 75 76 int main() 77 { 78 srand((unsigned)time(0)); 79 int N; 80 cout << "输入元素个数:"; 81 cin >> N; 82 int a[20]; 83 for (int i = 0; i<N; i++) 84 { 85 a[i] = rand() % 20 - 10; 86 cout << a[i] << " "; 87 } 88 cout << endl; 89 struct ret w = max2(a, N); //调用max2函数,求跨越零点的最值 90 struct ret q = max1(a, N); 91 if (w.max>q.max) 92 { 93 cout << "最大和为:" << w.max << "\n起始位置:" << w.end + 1 << "\n结束位置:" << w.start - 1 << endl; 94 } 95 else 96 { 97 cout << "最大和为:" << q.max << "\n起始位置:" << q.start << "\n结束位置:" << q.end << endl; 98 } 99 return 0; 100 }
五、运行结果截图
六、项目计划日志:
周活动总结表
姓名:张莹荧 日期:2016-03-26
日期/任务 | 听课 | 编写程序 | 阅读课本 | 考研复习 | 日总计 | ||
周日3.20 | 60 | 120 | 120 | 300 | |||
周一 | 300 | 30 | 120 | 450 | |||
周二 | 300 | 30 | 30 | 120 | 480 | ||
周三 | 200 | 180 | 180 | 560 | |||
周四 | 300 | 30 | 120 | 450 | |||
周五 | 100 | 180 | 30 | 310 | |||
周六 | 30 | 30 | |||||
周总结 | 1200 | 480 | 240 | 660 | 2580 |
阶段时间和效率 周数:3
不包括上一周在内的累计时间
总计 | 1200 | 480 | 240 | 660 | 2580 | ||
平均 | 1200 | 480 | 240 | 660 | 2580 | ||
最大 | 1200 | 480 | 240 | 660 | 2580 | ||
最小 | 1200 | 480 | 240 | 660 | 2580 |
以前各周的累计时间
总计 | 1200 | 480 | 240 | 660 | 2580 | ||
平均 | 1200 | 480 | 240 | 660 | 2580 | ||
最大 | 1200 | 480 | 240 | 660 | 2580 | ||
最小 | 1200 | 480 | 240 | 660 | 2580 |
七、时间记录日志:
学生:张莹荧 日期:2016-03-26
教师:王建民 课程: PSP
日期 | 开始时间 | 结束时间 | 中断时间 | 净时间 | 活动 | 备注 |
3.22 |
14:30 16:10 |
16:00 17:40 |
0 0 |
90 90 |
编程 阅读课本 |
中间上网、休息 |
3.23 |
8:00 14:00 |
12:00 15:50 |
40 10 |
200 100 |
上课 | 课间休息 |
3.24 |
14:30 19:00 |
17:40 19:30 |
10 0 |
180 30 |
编程 阅读课本 |
中间休息 |
3.25 |
12:30 19:00 |
13:30 19:30 |
0 0 |
60 30 |
编程 阅读课本 |
八、缺陷记录日志:
学生: 张莹荧,李俏
日期: 2016-03-26
教员: 王建民
程序号: 3
日期 | 编号 | 类型 | 引入阶段 | 排除阶段 | 修复时间 | 修复缺陷 |
3.26 | 1 | 函数 | 设计 | 编译 | 15min | |
描述:描述:求最大子数组的和的函数封装不恰当。 | ||||||
3.26 | 2 | 结果 | 编码 | 编译 | 15min | |
描述:没有考虑好最大子数组结果与其他元素的结果的关系。 | ||||||
3.26 | 3 | 算法 | 编码 | 查资料、问同学 | 30min | |
描述:时间复杂度不符合要求。 |
九、结对开发队友: