二维数组求最大子数组和(环形)

一、实验题目

      返回一个二维数组中最大子数组的和。

      实验要求:

      输入一个二维整形数组,数组里有正数也有负数。
      二维数组首尾相接,象个一条首尾相接带子一样。
      数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
      求所有子数组的和的最大值。要求时间复杂度为O(n)。
二、实验思路
     这次我们设计的实验是手动输入二维数组的行数和列数,二维数组的环形求和我们设计的思路和一位数组的类似,就是把求完的数组的第一列放到最后,依次类推。求最大的子数组和时和二维数组的求和类似,即:输入的二维数组是 -1  2

                                                                           3  4       

                                                                          -5  9

    (1)首先计算出第一行中有关-1的所有的子数组,然后计算出有关2的子数组,同样的道理可以计算第二行和第三行中的字数组。   

    (2)把上面计算出来的有关行中的子数组放在一个  b[3][3]即为 -1  1  2        的数组中。  

                                                                                         3  7  4                       

                                                                                       -5  4  9    

     (3)再求b[3][3]中的子数组的最大值,这次应该是按列来求。首先计算第一列中的子数组中的最大的数,先计算-1,然后计算-1+3,然后计算 -1+3+5,求出最大的来,再3+(-5)和max比较大小,求出最大的,再(-5)和max比较大小。同理求第二、三列。即可得出最大的来。

三、源程序

 1 //信1201-2班 司新红 万彤
 2 #include "stdafx.h"
 3 #include "iostream"
 4 using namespace std;
 5 int main()
 6 {
 7     int hang,lie;
 8     int a;
 9     int i,j;
10     int s;//    求和
11     int count;
12     int max;
13     cout<<"请输入二维数组的行数:";
14     cin>>hang;
15     cout<<"请输入二维数组的列数:";
16     cin>>lie;    
17     int **A;//定义动态二维数组
18     int **B;
19     a=lie*lie;
20     A=new int*[hang];
21     for(int k=0;k<hang;k++)
22     {
23         A[k]=new int[lie];
24     }
25     B=new int*[hang];
26     for(int l=0;l<hang;l++)
27     {
28         B[l]=new int[a];
29     }
30 
31     /*数组初始化*/
32 
33     cout<<"请输入二维数组中的元素"<<endl;
34     for(int i=0;i<hang;i++)
35     {
36         for(int j=0;j<lie;j++)
37         {
38             cin>>A[i][j];
39         }
40     }
41 
42 
43     /*二维数组压缩函数*/
44 
45 
46     for(i=0;i<hang;i++)
47     {
48         count=0;
49         for(j=0;j<lie;j++)
50         {
51             s=0;
52             for(int l=0;l<lie;l++)                            //每一行按顺序进行枚举存入数组中
53             {
54                 s=s+A[i][l+j];
55                 B[i][count+l]=s;
56             }
57             count=count+lie;
58             A[i][lie+j]=A[i][j];
59         }
60     }
61 
62 
63     max=B[0][0];                                                //将数组的第一个数赋值给max
64     for(j=0;j<a;j++)
65     {
66         for(i=0;i<hang;i++)
67         {
68             s=0;
69             for(int r=0;r<hang-i;r++)
70             {
71                 s=s+B[r+i][j];                            //逐列对数组进行枚举,求最大值
72                 if(max<s)
73                 {
74                     max=s;
75                 }
76             }
77         }
78     }
79     cout<<"最大子数组之和为:"<<max<<endl;
80     return 0;
81 }

四、实验截图

五、心得体会

     之前我们的数组都是采用的固定长度,但是这次我和小伙伴有了一个突破,就是手动输入行和列,其实我感觉这还是一个挺大的突破的(有一点点的小骄傲吧)。虽然在编程的过程中也遇到了一定的困难,但是我们都克服了,我感觉这就是进步。思想虽然还是原来的思想,但是在编写的过程中还是有一定的难度的。通过编写这次的程序我又增加了自信。

原文地址:https://www.cnblogs.com/zgsxh/p/4390327.html