• 返回一个整数数组中最大子数组的和(数组首尾相连)


    一:题目内容及设计思路

    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()==' '时,跳出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() != '
    ')
    	{
    		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分钟调试循环链表问题解决,用另外的指针代替头结点移动去分开循环链表。

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

  • 相关阅读:
    java做微信支付notify_url异步通知服务端的写法
    QT如何编译出带调试信息的qtwebkit库
    Vmware 占用宿主机硬盘空间只增不减
    vmware linux无法正常上网
    Linux中find常见用法示例
    计算机网络OSI参考模型与tcp/ip四层模型
    Core开发-后台任务利器Hangfire使用
    Azure构建PredictionIO和Spark的推荐引擎服务
    NET MVC+EF6+Bootstrap
    服务器
  • 原文地址:https://www.cnblogs.com/pengchengwanli/p/5325051.html
Copyright © 2020-2023  润新知