求二维整形数组的子数组的和最大的子数组

 成员:冯小兰  迟真真 

  这次课上实践内容为:在之前求一位数组最大子数组和的基础上,改为求二维整数数组的最大子数组和。

   首先,正确理解二维数组的子数组,如下一个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);
}

运行结果:

posted @ 2014-03-19 18:01  真真-是我  阅读(191)  评论(0编辑  收藏  举报