成员:冯小兰 迟真真
这次课上实践内容为:在之前求一位数组最大子数组和的基础上,改为求二维整数数组的最大子数组和。
首先,正确理解二维数组的子数组,如下一个3行4列的二维数组,其最大子数组和为绿色元素和:
所以,我们考虑的求出数组中所有子数组的和,思路如下:
用数组A[m][n]的左上角A[xa][ya]和右下角A[xb][yb]来确定一个数组,
xb的取值在[0,m];
yb的取值在[0, n];
xa<=xb;
ya<=yb;
确定了左上角和右下角后,子数组也就确定了,然后用for循环求子数组中元素的和;
求子数组和代码如下:
1 for(xb=0;xb<m;xb++) //子数组右下角行下标 2 { 3 for(yb=0;yb<n;yb++) //子数组右下角列下标 4 { 5 for(xa=0;xa<=xb;xa++) //子数组左上角行下标 6 { 7 for(ya=0;ya<=yb;ya++) //子数组左上角列下标 8 { 9 tempSum = 0; 10 for(i=xa;i<=xb;i++) //求子数组的和 11 { 12 for(j=ya;j<=yb;j++) 13 { 14 tempSum +=*((int*)arrayA + n*i + j); //((int*)arrayA + n*i + j)即是arrayA[i][j] 15 } 16 }
其中也遇到一个问题,二维数组大小都不确定,要用二维数组做形参。查阅谭浩强的《C程序设计》,最终用指针做形参。
在主函数中定义二维数组时同样也用指针,完整代码如下:
1 #include<stdio.h> 2 #define M 100 3 void main() 4 { 5 void getMaxSum(int **arrayA,int m,int n); 6 int a[M][M]; 7 int *p=a[0]; //这里使指针变量p指向0行0列元素地址 8 int m; 9 int n; 10 int i; 11 int j; 12 printf("数组行数m="); 13 scanf("%d",&m); 14 printf("数组列数n="); 15 scanf("%d",&n); 16 for(i=0;i<m;i++) //输入数组 17 { 18 for(j=0;j<n;j++) 19 { 20 scanf("%d",(p+n*i+j)); 21 } 22 } 23 printf("array a: "); 24 for(i=0;i<m;i++) //输出数组 25 { 26 for(j=0;j<n;j++) 27 { 28 printf("%5d",*(p+n*i+j));//*(p+n*i+j)=a[i][j] 29 } 30 printf(" "); 31 } 32 getMaxSum((int*)p,m,n); 33 } 34 35 void getMaxSum(int **arrayA,int m,int n) 36 { 37 int maxSum =0; //初始值 38 int tempSum = 0;//临时存储子数组的和 39 int i,j;//循环用 40 int a,b,c,d; 41 int xb,yb,xa,ya; 42 for(xb=0;xb<m;xb++) //子数组右下角行下标 43 { 44 for(yb=0;yb<n;yb++) //子数组右下角列下标 45 { 46 for(xa=0;xa<=xb;xa++) //子数组左上角行下标 47 { 48 for(ya=0;ya<=yb;ya++) //子数组左上角列下标 49 { 50 tempSum = 0; 51 for(i=xa;i<=xb;i++) //求子数组的和 52 { 53 for(j=ya;j<=yb;j++) 54 { 55 tempSum +=*((int*)arrayA + n*i + j); //*((int*)arrayA + n*i + j)即是arrayA[i][j] 56 } 57 } 58 if(tempSum > maxSum) 59 { 60 maxSum = tempSum; 61 a=xa; 62 b=xb; 63 c=ya; 64 d=yb; 65 } 66 } 67 } 68 } 69 } 70 71 printf("子数组从左上角a[%d][%d]",a,c); 72 printf("到右下角a[%d][%d]的和最大为 %d ",b,d,maxSum); 73 }
运行结果: