最大子矩阵(C语言实现)

算法核心:
先将二维数组处理为一维数组,再对一维数组进行最大连续子序列求和,这里最大连续子序列求和采用的是递推的方法。

算法步骤:
(1)将原矩阵初始化,并创建一个临时二维矩阵,该矩阵的第i行表示的是原矩阵前i行的和;
(2)采用穷举的方法,计算二维矩阵所有可能的连续行的列的和,使其压缩为一维数组;
(3)对步骤(2)中得到的每一个数组进行最大子序列求和,同时,不断更新最大值。

实例以及代码
问题描述:给定一个矩阵,找到最大的子矩阵。

//定义数据,A是原矩阵,t是临时矩阵,用于存储行的和
int A[10][10]={0},t[10][10]={0};
int t1,t2;  //一维数组的最大子列和的范围
int l1,l2,h1,h2; //最大子矩阵的范围
//初始化矩阵
int Input(){
	int n,i,j;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			scanf("%d",&A[i][j]);
	return n;
}
//计算一个临时的矩阵和矩阵
void Temporary(int n){
	int i,j;
	for(i=0;i<n;i++)
		t[0][i]=A[0][i];
	for(i=1;i<n;i++)
		for(j=0;j<n;j++)
			t[i][j]=A[i][j]+t[i-1][j];
}
//对一维数组进行最大子列求和
int OneSequence(int a[],int n){
	int i,sum=0,max=-100;
	int s=0,e=0;
	for(i=0;i<n;i++)
	{
		sum=a[i]+sum;
		if(max<sum)
		{
			max=sum;
			t1=s;
			t2=e;
		}
		if(sum<0)
		{
			sum=0; 
			s=i+1;
			e=i+1;
		}
		else
			e++;
	}
	//printf("%d----%d max=%d",t1,t2,max);
	return max;
}

//处理二维矩阵的行,压缩为一维数组
int TwoSequence(int n){
	int i,j,k;
	int temp[20],max=-100,m;
	for(i=-1;i<n;i++)
		for(j=0;j<n;j++)
		{
			if(i<0)
			{
				for(k=0;k<n;k++)
					temp[k]=t[j][k];
			}
			else
			{
				for(k=0;k<n;k++)
					temp[k]=t[j][k]-t[i][k];
			}
			m=OneSequence(temp,n);  //处理一维数组
			if(m>max)
			{
				max=m;
				h1=i;h2=j;
				l1=t1;l2=t2;
			}
		}
	return max;
}
//格式化输出
void Output(int max){
	int i,j;
	printf("最大子矩阵为:\n");
	for(i=h1+1;i<=h2;i++)  //输出子矩阵
	{
		for(j=l1;j<=l2;j++)
			printf("%d\t",A[i][j]);
		printf("\n");
	}
	printf("最大子矩阵和为:%d",max);  //输出 最大和
}

//主函数,负责调用以上函数
int main(){
	int n,res;
	n=Input();
	Temporary(n);
	res=TwoSequence(n);
	Output(res);
	return 0;
}

运行结果:
在这里插入图片描述

原创文章 16 获赞 5 访问量 1000

猜你喜欢

转载自blog.csdn.net/qq_42453280/article/details/106036576
今日推荐