个人作业(3 ---二维数组求最大子数组)
题目要求:
输入一个二维数组,在二维数组中求一个具有二维子数组的矩阵块
解题思路:
最初设想的是根据一维数组的方式求出每一行的最大子数组,然后根据每一行子数组之间的交集,及是题目所需的矩阵块,但是后来在编写过程中发现,每一行的最大子数组并不一定会有交集,并且,其最大子数组的交集也不一定是所需的矩阵,并且在编写过程中会有很多的情况,需要很多的判断,这样对于循环的编写非常不便。最后我采用的是最笨的方法,就是通过把所有的矩阵都求一遍,并比较大小,计算最大的子数组 。这种方法达到了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; } }
实验结果截图:
总结:这个问题中如何确定矩阵的位置是一个难点,寻找一个最大的矩阵块特别困难,而如果采用这种较为简单直接的方式又需要特别大的计算量。