一:题目内容及设计思路

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
星期四 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分钟调试循环链表问题解决,用另外的指针代替头结点移动去分开循环链表。

然后再构造子数组结构来解决输出最大子数组位置问题。