最大子数组二

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子数组二相关的知识,希望对你有一定的参考价值。

一、实验思路:
1.定义一个整型数组num[n],随机生成数组中元素的值
2.把这个整形数组连成环,就是把这个数组中的每一个元素都当一次头,邻接的左元素做尾,遍历一次数组,找出每一个元数组的子数组最大和,存放在max_a[]中
3.定义一个二维数组dpo[n][2],dpo[i][0]不包含num[i]子数组之和最大值,dpo[i][1]包含num[i]子数组之和最大值
4.采用循环递归的方式,调用max函数计算dpo[i][0],dpo[i][1],计算包含数组元素本身和不包含本身的前子数组最大和的情况,循环递归求出max_a[j],定义数组arr[i][j]用来存放最大和子数组,通过比较
dpo[i][0],dpo[i][1]最大子数组中的元素,存放在arr[i][j]中,j表示子数组的位置
5.比较max_a[]中元素的最大值,找出最大和赋给Max,同时返回元素的位置,就是最大和数组的位置,救是arr[i][j]在哪个元数组中
6.通过条件比较过滤到arr[i][j]中空元素,并将其倒序存放arr_1[]中,然后将arr_1[]倒序输出,救是最大子数组。

 1 #include<iostream>
 2 #include<string>
 3 #include<time.h>
 4 #define N 1000
 5 using namespace std;
 6 int main()
 7 {    
 8     srand((unsigned)time(NULL));
 9     int num[N],dpo[N][2];
10     int n;
11     cout<<"请输入数组的长度:"<<endl;
12     cin>>n;
13     cout<<"这个数组为:"<<endl;
14     for(int i=0;i<n;i++)
15     {
16         num[i]=-5+rand()%15;
17         if(num[i]==0)
18         {
19             num[i]=1+rand()%15;
20         }
21         cout<<num[i]<<" ";
22     }
23     cout<<endl;
24     cout<<"最大和子数组为:"<<endl;
25     int front,Max=-300,arr[100][100],max_a[N];//front是指数值环中的每一个元素都可以当头,Max指输出的最大值,max_a用来存放每个元数组的最大值
26     for(int j=0;j<n;j++)
27     {
28         front=num[0];
29         for(int i=1;i<n;i++)
30         {
31             num[i-1]=num[i];
32         }
33         num[n-1]=front;               //在数组环中让每一个元素当头,左边的元素当尾,遍历元数组 
34         dpo[0][0]=0;
35         dpo[0][1]=num[0];
36         for(int i=0;i<n;i++)          //找出每一个元数组的子数组最大和,存放在max_a[]中
37        {
38             dpo[i][0]=max(dpo[i-1][0],dpo[i-1][1]);
39             dpo[i][1]=max(dpo[i-1][1]+num[i],num[i]);
40             max_a[j]=max(dpo[i][0],dpo[i][1]);
41             if(dpo[i][0]<=dpo[i][1])      //找每一个元数组的最大和子数组,采用循环比较的方法
42             {   
43                 if(num[0]<0)
44                 {
45                     arr[0][j]=NULL;
46                 }
47                 arr[i][j]=num[i];
48             }
49             if(dpo[i][0]>dpo[i][1])
50             {
51                 if((dpo[i][1]==dpo[i-1][1]+num[i])&&(dpo[i][1]>0))
52                 {
53                     arr[i][j]=num[i];
54                 }
55                 else
56                 arr[i][j]=NULL;
57             }
58         }
59     }
60     int p=n-1,arr_1[N],m=0,k,j;     //arr[]用来存放最大子数组
61     for(int i=0;i<n;i++)            //比较每一个元数组的最大子数组的和,把最大的和赋给Max,
62     {
63         if(max_a[i]>Max)
64         {
65             Max=max_a[i];
66             j=i;                  //找出最大和所在的元数组
67         }
68     }
69     while(p>=0)                   //把最大和的子数组过滤出倒序存放在arr_1[]中
70     {
71         if(arr[p][j]==NULL)
72         {
73             p--;
74         }
75         if(arr[p][j]!=NULL)
76         {
77             while((arr[p][j]!=NULL)&&(p>=0))
78             {
79                 arr_1[m]=arr[p][j];
80                 m++;
81                 k=m;
82                 p--;
83             }
84             p=-1;    
85         }
86     }
87     for(int i=k-1;i>=0;i--)      //输出最大和子数组
88     {
89         cout<<arr_1[i]<<" ";
90     }
91     cout<<endl;
92     cout<<"最大数组和为:"<<endl;
93     cout<<Max<<endl;
94 }

二、实验截图:
技术分享技术分享

三、实验日志:

 

项目记录 日志:

 

听课

编写程序

阅读相关书籍

网上查找资料

日总计

周一

2

0

0

0

2

周二

0

1

1

0

2

周三

0

3

0.5

1

4.5

周四

2

0.5

0.5

0

3

周五

0

3

0.5

1

4.5

周六

0

1

0

1

2

周日

0

3

1

0

4

周总计

4

12.5

3.5

3

22

时间记录日志

日期

开始 时间

结束时间

中断时间

净时间

活动

备注

星期一

14:00

16:00

10

100

上课

软件工程

星期二

16:00

17:00

0

60

编程

数组问题

 

19:00

20:00

0

60

阅读书籍

 

构建之法

星期三

13:00

17:00

60

180

编程

 

 

19:00

21:00

30

90

阅读书籍

构建之法

星期四

14:00

16:00

10

100

上课

软件工程

 

19:00

20:00

0

60

编程 查找资料

数组问题

星期五

13:00

17:00

60

180

编程

数组问题

 

17:00

18:00

0

60

上网

查资料

星期六

12:00

14:00

30

90

编程

数组问题

星期日

9:00

11:00

0

180

编程

数组问题二

缺陷记录日志:

日期

编号

类型

引入阶段

排除阶段

修复阶段

修复缺陷

3/27

1

数组变环阶段

 

 

30min

 

在数组连接成环时,让数组中的每一个元素都当一次头,循环遍历一次

2

最大和子数组的返回

 

 

3h

 

在编写这一步骤时遇到困难,我返回的方法比较笨拙,在遍历最大和的时候,做出最大和子数组所在的元数组,在元数组循环遍历求最大和时,通过比较dpo[i][0],dpo[i][1]的大小,来找出最大子数组

 四、实验总结:

在这次实验中,我们遇到了两个难题,一是如何将数组连成环,二是如何返回最大和数组的值,这两个问题我们讨论了很久,虽然思路还是不太简单,但是还是解出来了,我觉得结对开发在我们做项目时效率要提高很多,一个人的能力毕竟是有限的,两个人相互合作,相互补充,才能在更短的时间内,更高效率的而完成工作。

我的伙伴 鲁鑫:http://www.cnblogs.com/LUXIN123/

以上是关于最大子数组二的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3155 Hard Life(最大密度子图)

NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段

LeetCode 1800. 最大升序子数组和

分治法求解最大子段和问题

课堂测试总结-数组

leetcode-53 maximum-subarray(最大子序和)