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

一:题目内容及设计思路

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

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

原文地址:https://www.cnblogs.com/wangzongze/p/5325305.html