一:题目内容及设计思路
1.题目:
返回一个整数数组中最大数组的和(数组首尾相连)
2.要求:
(1)输入一个整型数组,数组里有正数也有负数。
(2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
(3)如果数组A[0],......,A[n-1]首尾相邻,允许A[i-1],......,A[n-1],A[0],......,A[i-2]之和最大。
(4)同时返回最大子数组的位置。
3.设计思路:
(1)利用while循环输入各个整数,用getchar()函数判断while循环是否结束,当用户按下回车键时,即getchar()=='\n'时,跳出while循环;
(2)记录下循环的次数,即数组长度;
(3)构造子数组结构SArray,包含属性Sdata、start、end分别表示子数组中的数、子数组的起始位置、子数组的终止位置;
(4)构造链表的存储结构LNode,包含属性data、position、*next分别表示链表结点中的数据、数据在原整数数组中的位置、指向结点的指针;
(5)在主函数中调用void CreateList(LinkList &L, int Group[], int n)函数将整数数组存入循环链表中;
(6)在主函数中调用SArray Divide(LinkList L, int length)函数,将含n个数的循环数组依次从各个点断开,产生n个含n个数组的单链数组;
(7)在SArray Divide(LinkList L, int length)函数中调用SArray Compare(LinkList L, int Length)函数,返回最大子数组。
4.结对开发伙伴:
姓名:王宗泽
博客名:二十划生
博客地址链接:http://www.cnblogs.com/wangzongze/
二:具体实现
1.实验代码
//返回一个整数数组中最大子数组的和(数组首尾相连) #include<iostream> #define N 100 using namespace std; //构造子数组结构 typedef struct SArray { int Sdata; //子数组中的数 int start; //子数组的起始位置 int end; //子数组的终止位置 }SArray; //构造链表的存储结构 typedef struct LNode { int data; //数 int position; //数所在数组中的位置 struct LNode *next; //指针 }LNode, *LinkList; //创建循环链表 void CreateList(LinkList &L, int Group[], int n) { L = new LNode; L->next = NULL; LNode *r; r = L; for (int i = 0; i < n - 1; i++) { LNode *p; p = new LNode; p->data = Group[i]; p->position = i + 1; p->next = NULL; r->next = p; r = p; } LNode *p; p = new LNode; p->data = Group[n - 1]; p->position = n; p->next = L->next; r->next = p; } //返回最大子数组 SArray Compare(LinkList L, int Length) { SArray MaxSum[N][2]; //MaxSum[N][0].Sdata表示前N-1个数中,最大的子数组 //MaxSum[N][1].Sdata表示前N-1个数的最大的子数组和加第N个数的和与第N个数相比的最大值 LNode *r; r = L->next; MaxSum[0][0].Sdata = MaxSum[0][1].Sdata = r->data; MaxSum[0][0].start = MaxSum[0][1].start = r->position; MaxSum[0][0].end = MaxSum[0][1].end = r->position; for (int i = 1; i < Length; i++) { if (MaxSum[i - 1][0].Sdata > MaxSum[i - 1][1].Sdata) { MaxSum[i][0].Sdata = MaxSum[i - 1][0].Sdata; MaxSum[i][0].start = MaxSum[i - 1][0].start; MaxSum[i][0].end = MaxSum[i - 1][0].end; } else { MaxSum[i][0].Sdata = MaxSum[i - 1][1].Sdata; MaxSum[i][0].start = MaxSum[i - 1][1].start; MaxSum[i][0].end = MaxSum[i - 1][1].end; } if (MaxSum[i - 1][1].Sdata + r->next->data > r->next->data) { MaxSum[i][1].Sdata = MaxSum[i - 1][1].Sdata + r->next->data; MaxSum[i][1].start = MaxSum[i - 1][1].start; MaxSum[i][1].end = r->next->position; } else { MaxSum[i][1].Sdata = r->next->data; MaxSum[i][1].start = r->next->position; MaxSum[i][1].end = r->next->position; } r = r->next; } if (MaxSum[Length - 1][0].Sdata > MaxSum[Length - 1][1].Sdata) { return MaxSum[Length - 1][0]; } else { return MaxSum[Length - 1][1]; } } //将含n个数的循环数组依次从各个点断开,产生n个含n个数组的单链数组 SArray Divide(LinkList L, int length) { LinkList LGroup[N]; //头节点集合 LNode *r; r = L; for (int i = 0; i < length; i++) { LGroup[i] = r; r = r->next; } SArray MaxGroup[N]; //分成的各个数组的最大子数组的集合 for (int i = 0; i < length; i++) { MaxGroup[i].Sdata = Compare(LGroup[i], length).Sdata; MaxGroup[i].start = Compare(LGroup[i], length).start; MaxGroup[i].end = Compare(LGroup[i], length).end; } SArray Max = MaxGroup[0]; //各个数组的最大子数组和的最大值 for (int i = 1; i < length; i++) { if (Max.Sdata < MaxGroup[i].Sdata) { Max.Sdata = MaxGroup[i].Sdata; Max.start = MaxGroup[i].start; Max.end = MaxGroup[i].end; } } return Max; } int main() { int Number[N]; //整数数组 int length; //数组长度 cout << "请输入一个整型数组:" << endl; cin >> Number[0]; length = 1; while (getchar() != '\n') { cin >> Number[length++]; } LinkList L; CreateList(L, Number, length); cout << "该数组中的最大的子数组和为:"; cout << Divide(L, length).Sdata << endl; cout << "该最大子数组的起始位置为:"; cout << Divide(L, length).start << endl; cout << "该最大子数组的终止位置为:"; cout << Divide(L, length).end << endl; return 0; }
2.运行结果截图
三:总结
本次实验是在上一次实验的基础上完成的,由于思路清晰,模块划分得当,所以花的时间并不是很多。
项目计划总结:
日期\任务 | 听课 | 编写程序 | 查阅资料 | 日总计 |
星期一 | 2 | 1 | 3 | |
星期二 | ||||
星期三 | 1 | 1 | ||
星期四 | 2 | 2 | ||
星期五 | 1 | 1 | ||
星期六 | 2 | 2 | ||
星期日 | 2 | 2 | ||
周总计 | 4 | 5 | 2 |
11 |
时间记录日志:
日期 | 开始时间 | 结束时间 | 中断时间 | 静时间 | 活动 | 备注 |
3/21 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程 |
19: 30 | 20: 40 | 10 | 60 | 查阅资料 | 查阅数据结构课本 | |
3/22 | ||||||
3/23 | 19:20 | 20:20 | 60 | 查阅资料 | 查阅数据结构课本 | |
14:20 | 15:30 | 10 | 60 | 编写程序 | 编写周二的程序 | |
3/24 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程 |
3/25 | 19:30 | 20:40 | 10 | 60 | 编写程序 | 编写周二的程序 |
3/26 | 9:20 | 11:40 | 10 | 130 | 编写程序 | 编写周四的程序 |
13:20 | 14:20 | 60 | 写博客 | 写博客 | ||
3/27 | 7:30 | 9:30 | 120 | 编写程序 | 编写周四的程序 | |
9:30 | 10:10 | 40 | 写博客 | 写博客 |
缺陷记录日志:
日期 | 编号 | 引入阶段 | 排除阶段 | 修复时间&问题描述 |
3/21 | 1 | |||
3/22 | 2 | |||
3/23 | 3 | 编码 | 查询资料 | 编写程序,没弄明白getchar()函数,半小时后解决问题 |
3/24 | 4 | |||
3/25 | 5 | 编码 | 调试 | 编写程序,调试,解决递归问题,程序完成 |
3/26 | 6 | 编码 | 调试 | 顺利将数组存入循环链表中,发现不能将循环链表分开 |
3/27 | 7 | 编码 | 调试 |
花了30分钟调试循环链表问题解决,用另外的指针代替头结点移动去分开循环链表。 然后再构造子数组结构来解决输出最大子数组位置问题。 |