一:题目内容及设计思路
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分钟调试循环链表问题解决,用另外的指针代替头结点移动去分开循环链表。 然后再构造子数组结构来解决输出最大子数组位置问题。 |