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

一:题目内容及设计思路

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://home.cnblogs.com/u/pengchengwanli/

二:具体实现

1.实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//返回一个整数数组中最大子数组的和(数组首尾相连)
#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 13
星期二    
星期三  1
星期四2  2
星期五 1 1
星期六 2 2
星期日 2 2
周总计452

11

 

时间记录日志:

日期开始时间结束时间中断时间静时间活动备注
3/2114:0015:5010100听课软件工程
 19:  3020:  401060查阅资料查阅数据结构课本
3/22      
       
3/2319:20 20:20 60查阅资料查阅数据结构课本
 14:2015:301060编写程序编写周二的程序
3/2414:0015:5010100听课软件工程
       
3/2519:30 20:401060编写程序编写周二的程序
       
3/269:20 11:4010130编写程序编写周四的程序
 13:2014:20 60写博客写博客
3/277:309:30 120编写程序编写周四的程序
 9:3010:10 40写博客写博客

缺陷记录日志:

日期编号引入阶段排除阶段修复时间&问题描述
3/211   
3/222   
3/233编码查询资料  编写程序,没弄明白getchar()函数,半小时后解决问题 
3/244   
3/255编码调试编写程序,调试,解决递归问题,程序完成
3/266编码调试顺利将数组存入循环链表中,发现不能将循环链表分开
3/277编码调试

花了30分钟调试循环链表问题解决,用另外的指针代替头结点移动去分开循环链表。

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

转载于:https://www.cnblogs.com/wangzongze/p/5325305.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值