软件工程——求二维数组所有子矩阵的和的最大值
题目:返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
结对编程要求:
两人结对完成编程任务。
一人主要负责程序分析,代码编程。
一人负责代码复审和代码测试计划。
一、设计思想
求二维数组最大子数组的和,可以转化为求一维数组最大子数组的和
我们有一个最初的二维数组a[n][m],找它的 最大子数组之和
1.我们先建立一个新的二维数组b[n][m],二维数组b[j][k] 存放的是a[j][k](0<=j<n,0<=k<m) 这一点到 a[0][0] 的最大值
2.循环:从a[0][0]开始 以此是 a[0][1]、 a[0][2]……a[0][m]、
a[1][0]、 a[1][1]……a[1][m]、
a[2][0]、 a[2][1]……a[2][m]、
……
a[n][0]、 a[n][1]……a[n][m]、
具体循环工作:当循环到a[j][k](0<=j<n,0<=k<m)则求的是 a[j][k]到 a[0][0] 的最大值
计算方法:根据b[j-1][k]、b[j][k-1]、b[j-1][k-1]的正负情况,来计算b[j][k],根据包含a[j][k]的各种矩阵情况,求得最大值。
3.求出b[m][n]中的最大值。
二、源代码
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int i,j; 6 int a[3][3]={-1,-2,3,1,-3,2,4,4,-1}; 7 int b[3][3]; 8 int max=a[0][0]; 9 for(i=0;i<3;i++) 10 { 11 for(j=0;j<3;j++) 12 { 13 cout<<a[i][j]<<' '; 14 } 15 cout<<endl; 16 } 17 for(i=0;i<1;i++) 18 { 19 b[0][0]=a[0][0]; 20 for(j=0;j<3;j++) 21 { 22 if(a[0][j-1]<0) 23 { 24 b[0][j]=a[0][j]; 25 } 26 else 27 { 28 b[0][j]=b[0][j-1]+a[0][j]; 29 } 30 } 31 } 32 for(i=1;i<3;i++) 33 { 34 for(j=0;j<1;j++) 35 { 36 if(a[i-1][0]<0) 37 { 38 b[i][0]=a[i][0]; 39 } 40 else 41 { 42 b[i][0]=b[i-1][0]+a[i][0]; 43 } 44 } 45 } 46 for(i=1;i<3;i++) 47 { 48 for(j=1;j<3;j++) 49 { 50 if(b[i-1][j-1]<0) 51 { 52 if(b[i-1][j]>=0&&b[i][j-1]>=0) 53 { 54 if(b[i][j-1]>=b[i-1][j]) 55 { 56 b[i][j]=b[i][j-1]+a[i][j]; 57 } 58 else 59 { 60 b[i][j]=b[i-1][j]+a[i][j]; 61 } 62 } 63 else if(b[i-1][j]>=0&&b[i][j-1]<=0) 64 { 65 b[i][j]=b[i-1][j]+a[i][j]; 66 } 67 else if(b[i-1][j]<=0&&b[i][j-1]>=0) 68 { 69 b[i][j]=b[i][j-1]+a[i][j]; 70 } 71 else 72 { 73 b[i][j]=a[i][j]; 74 } 75 } 76 else 77 { 78 if(b[i-1][j]>=0&&b[i][j-1]>=0) 79 { 80 b[i][j]=a[i][j]+b[i-1][j]+b[i][j-1]-b[i-1][j-1]; 81 } 82 else if(b[i-1][j]>=0&&b[i][j-1]<=0) 83 { 84 b[i][j]=a[i][j]+b[i-1][j]-b[i-1][j-1]; 85 } 86 else if(b[i-1][j]<=0&&b[i][j-1]>=0) 87 { 88 b[i][j]=a[i][j]+b[i][j-1]-b[i-1][j-1]; 89 } 90 else 91 { 92 b[i][j]=a[i][j]; 93 } 94 } 95 } 96 } 97 for(i=0;i<3;i++) 98 { 99 for(j=0;j<3;j++) 100 { 101 cout<<b[i][j]<<" "; 102 } 103 cout<<endl; 104 } 105 for(i=0;i<3;i++) 106 { 107 for(j=0;j<3;j++) 108 { 109 if(b[i][j]>max) 110 max=b[i][j]; 111 } 112 } 113 cout<<"max="<<max<<endl; 114 return 0; 115 }
三、运行结果截图
有正有负:
全是正数:
全是负数:
四、心得体会
首先是设计思想,一开始我们思路比较混乱,先找到一共有多少个子矩阵,想着怎么样才能把整个数组的所有子矩阵都遍历一遍,也不知道具体怎么样用程序实现。
课上有同学介绍他们自己的思路,使我们确定了一条可以执行的思路。
程序的编写具有极大挑战性,由于是二维数组,行列老是弄混,元素想加时情况又多,要随时注意思路清晰。
附: