求一个矩阵中最大的二维矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码
分析:
其实我感觉题目给的例子是错误的,既然矩阵元素都是正数,那么整个矩阵的和不是最大吗?
按照这个思路我写了一段代码(利用最大子段和)。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define iRow 3
#define iCol 3
typedef struct
{
int imaxValue; //最大子段的和
int iFront; //最大子段的起点坐标
int iRear; //最大子段的终点坐标
}maxInfo;
int arr[10][10]; //二维矩阵
void CreateArray(); //初始化矩阵
maxInfo calBCS(int *arrBCS); //求最大子段和
void calBMetricSum(); //计算最大二维子矩阵的和
int main()
{
CreateArray();
calBMetricSum();
return 0;
}
void CreateArray()
{
int i,j;
FILE *infile=fopen("E://a.txt","r");
if (!infile)
{
return ;
}
for (i=0;i<iRow;i++)
{
for (j=0;j<iCol;j++)
{
fscanf(infile,"%d",&arr[i][j]);
}
}
fclose(infile);
}
maxInfo calBCS(int *arrBCS)
{
int i,itempSum=0,iFront=0,iRear=0; //itempSum为存储当前和,iFront为当前子段的起点坐标,iRear为终点坐标
maxInfo maxinfo; //记录最大子段的信息
maxinfo.imaxValue=-32767; //先赋最小值
for (i=0;i<iCol;i++)
{
if (arrBCS[i]>=itempSum+arrBCS[i])
{
itempSum=arrBCS[i];
iFront=iRear=i;
}
else
{
itempSum+=arrBCS[i];
iRear++;
}
if (itempSum>maxinfo.imaxValue)
{
maxinfo.imaxValue=itempSum;
maxinfo.iFront=iFront;
maxinfo.iRear=iRear;
}
}
return maxinfo;
}
void calBMetricSum()
{
int i,j,k,iRowUp,iRowDown; //iRowUp为最大子矩阵的第一行所在原矩阵中的行数,iRowDown为最下一行所在的行数
int arrBCS[10]; //记录当前矩阵每列的和,即子序列
maxInfo backValue,maxSum; //backValue为从最大子段和函数返回的信息,maxSum为最大子矩阵的相关信息
maxSum.imaxValue=-32767;
for (i=0;i<iRow;i++)
{
memset(arrBCS,0,sizeof(arrBCS));
for (j=i;j<iRow;j++)
{
for (k=0;k<iCol;k++)
{
arrBCS[k]+=arr[j][k]; //累加当前矩阵每一列的和
}
backValue=calBCS(arrBCS);
if (backValue.imaxValue>maxSum.imaxValue)
{
maxSum=backValue;
iRowUp=i;
iRowDown=j;
}
}
}
printf("The max sum of the metric is : %d\n",maxSum);
for (i=iRowUp;i<=iRowDown;i++)
{
for (j=maxSum.iFront;j<=maxSum.iRear;j++)
{
printf("%3d",arr[i][j]);
}
printf("\n");
}
}