题目要求:
输入一个二维数组,在二维数组中求一个具有二维子数组的矩阵块
解题思路:
最初设想的是根据一维数组的方式求出每一行的最大子数组,然后根据每一行子数组之间的交集,及是题目所需的矩阵块,但是后来在编写过程中发现,每一行的最大子数组并不一定会有交集,并且,其最大子数组的交集也不一定是所需的矩阵,并且在编写过程中会有很多的情况,需要很多的判断,这样对于循环的编写非常不便。最后我采用的是最笨的方法,就是通过把所有的矩阵都求一遍,并比较大小,计算最大的子数组 。这种方法达到了o(n^6)所以计算量特别大。
遇到的问题:
由于用到了很多的循环嵌套,在编写过程中,出现了很多问题,为了能够减少循环的嵌套,我写了一个方法,通过矩阵的第一个和最后一个的位置,计算出他的值,这样就可以通过调用这个方法,减少嵌套了。
package test;
/*
* 求二位数组的最大子数组
*/
import java.util.Scanner;
public class Erwei1 {
static Scanner in = new Scanner(System.in);
static int[][] a = new int[20][20]; //存放输入的二维数组
public static void main(String[] args) {
// TODO 自动生成的方法存根
int row;
int clo;
int value = 0;
System.out.println("输入数组的行数和列数");
row = in.nextInt();
clo = in.nextInt();
System.out.println("输入数组元素");
for(int i = 0; i < row; i++)
{
for(int j = 0; j < clo; j++)
{
a[i][j] = in.nextInt();
}
}
int minh = 0; //矩形中行的较小值
int maxh = 0; //矩形中行的较大值
int minl = 0; //矩形中列的较小值
int maxl = 0; //举行中列的较大值
int max = a[0][0];
for(int i1 = 0 ; i1 < row ; i1++)
{
for(int j1 = 0; j1 < clo ; j1++)
{
for(int i2 = i1; i2 < row ; i2++)
{
for(int j2 = j1 ; j2 < clo ; j2++)
{
value = maxsum(i1, j1, i2, j2); //调用矩阵求和函数,计算每一个矩阵的值
if (max < value ) {
max = value;
//记录矩阵的相应位置,便于进行输出
minh = i1;
minl = j1;
maxh = i2;
maxl = j2;
}
value = 0;
}
}
}
}
System.out.println("最大子数组为" + max);
System.out.println("其最大矩阵序列为:"); //输出具有最大子数组的矩阵块
for(int i = minh; i <= maxh ; i++)
{
for(int j = minl; j <= maxl; j++)
{
System.out.print(a[i][j] + "\t");
}
System.out.println("");
}
}
//求一个矩形框中的数值
public static int maxsum(int minh,int maxh,int minl,int maxl)
{
int sum=0;
for(int i = minh; i <= maxh ; i++)
{
for(int j = minl; j <= maxl; j++)
{
sum += a[i][j];
}
}
return sum;
}
}
实验结果截图:
总结:这个问题中如何确定矩阵的位置是一个难点,寻找一个最大的矩阵块特别困难,而如果采用这种较为简单直接的方式又需要特别大的计算量。