求二维整形数组的子数组的和最大的子数组
成员:冯小兰 迟真真
这次课上实践内容为:在之前求一位数组最大子数组和的基础上,改为求二维整数数组的最大子数组和。
首先,正确理解二维数组的子数组,如下一个3行4列的二维数组,其最大子数组和为绿色元素和:
所以,我们考虑的求出数组中所有子数组的和,思路如下:
用数组A[m][n]的左上角A[xa][ya]和右下角A[xb][yb]来确定一个数组,
xb的取值在[0,m];
yb的取值在[0, n];
xa<=xb;
ya<=yb;
确定了左上角和右下角后,子数组也就确定了,然后用for循环求子数组中元素的和;
求子数组和代码如下:
for(xb=0;xb<m;xb++) //子数组右下角行下标 { for(yb=0;yb<n;yb++) //子数组右下角列下标 { for(xa=0;xa<=xb;xa++) //子数组左上角行下标 { for(ya=0;ya<=yb;ya++) //子数组左上角列下标 { tempSum = 0; for(i=xa;i<=xb;i++) //求子数组的和 { for(j=ya;j<=yb;j++) { tempSum +=*((int*)arrayA + n*i + j); //((int*)arrayA + n*i + j)即是arrayA[i][j] } }
其中也遇到一个问题,二维数组大小都不确定,要用二维数组做形参。查阅谭浩强的《C程序设计》,最终用指针做形参。
在主函数中定义二维数组时同样也用指针,完整代码如下:
#include<stdio.h> #define M 100 void main() { void getMaxSum(int **arrayA,int m,int n); int a[M][M]; int *p=a[0]; //这里使指针变量p指向0行0列元素地址 int m; int n; int i; int j; printf("数组行数m="); scanf("%d",&m); printf("数组列数n="); scanf("%d",&n); for(i=0;i<m;i++) //输入数组 { for(j=0;j<n;j++) { scanf("%d",(p+n*i+j)); } } printf("array a:\n"); for(i=0;i<m;i++) //输出数组 { for(j=0;j<n;j++) { printf("%5d",*(p+n*i+j));//*(p+n*i+j)=a[i][j] } printf("\n"); } getMaxSum((int*)p,m,n); } void getMaxSum(int **arrayA,int m,int n) { int maxSum =0; //初始值 int tempSum = 0;//临时存储子数组的和 int i,j;//循环用 int a,b,c,d; int xb,yb,xa,ya; for(xb=0;xb<m;xb++) //子数组右下角行下标 { for(yb=0;yb<n;yb++) //子数组右下角列下标 { for(xa=0;xa<=xb;xa++) //子数组左上角行下标 { for(ya=0;ya<=yb;ya++) //子数组左上角列下标 { tempSum = 0; for(i=xa;i<=xb;i++) //求子数组的和 { for(j=ya;j<=yb;j++) { tempSum +=*((int*)arrayA + n*i + j); //*((int*)arrayA + n*i + j)即是arrayA[i][j] } } if(tempSum > maxSum) { maxSum = tempSum; a=xa; b=xb; c=ya; d=yb; } } } } } printf("子数组从左上角a[%d][%d]",a,c); printf("到右下角a[%d][%d]的和最大为 %d\n",b,d,maxSum); }
运行结果: