标签:
一、设计思路
求出该二维数组的所有子数组,先确定一个位置为起点,然后向右下方依次以此起点为始的所有子数组,
图1—顺序求子数组
具体如上图1,顺序求出子数组,然后和max值相比较,若比max值大,则将该子数组和赋给max,并保存其位置,对该子数组的位置,只需要保存其首尾位置即可,
图2—保存子数组位置
如上图2所示,得到了最大子数组和与其位置,输出即可。
二、代码
1 package zishuzu; 2 3 import java.util.*; 4 5 public class zuixiaozishuzu { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 10 int m,n,M,N,max,sum; 11 int i,i1,i2,j,j1,j2; 12 int shouL,shouR,weiL,weiR; 13 Scanner sc = new Scanner(System.in); 14 System.out.println("输入二维数组的行数和列数:"); 15 m = sc.nextInt(); 16 n = sc.nextInt(); 17 System.out.println("输入该二位数组的取值范围(保证第一个数小于第二个数):"); 18 M = sc.nextInt(); 19 N = sc.nextInt(); 20 21 int[][] Shuzu = new int[m][n]; 22 for(i = 0;i < m;i++) 23 for(j = 0;j < n;j++) 24 { 25 Shuzu[i][j] = N + (int)(Math.random()*(M - N)); 26 } 27 System.out.println("该随机二维数组为:"); 28 for(i = 0;i < m;i++) 29 for(j = 0;j < n;j++) 30 { 31 System.out.print(Shuzu[i][j]+"\t"); 32 if(j == n - 1) 33 { 34 System.out.print("\n"); 35 } 36 } 37 38 sum =0; 39 max = Shuzu[0][0]; 40 shouL = 0; 41 shouR = 0; 42 weiL = 0; 43 weiR = 0; 44 45 for(i = 0;i < m;i++) 46 { 47 for(j = 0;j < n;j++) 48 { 49 for(i1 = i;i1 < m;i1++) 50 { 51 for(j1 = j;j1 < n;j1++) 52 { 53 for(i2 = i;i2 <= i1;i2++) 54 { 55 for(j2 = j;j2 <= j1;j2++) 56 { 57 sum = sum + Shuzu[i2][j2]; 58 } 59 } 60 if(max <= sum) 61 { 62 max = sum; 63 shouL = i; 64 shouR = j; 65 weiL = i1; 66 weiR = j1; 67 } 68 sum = 0; 69 } 70 } 71 } 72 } 73 74 System.out.println("最大子数组和为:"); 75 System.out.println(max); 76 System.out.println("最大子数组为:"); 77 for(i = shouL;i <= weiL;i++) 78 for(j = shouR;j <= weiR;j++) 79 { 80 System.out.print(Shuzu[i][j] + "\t"); 81 if(j == weiR) 82 { 83 System.out.print("\n"); 84 } 85 } 86 87 sc.close(); 88 }
三、实验结果
图3—结果1
图4—结果2
图5—结果3
四、开发过程
一个二维数组,当看到求最小子数组时,立马蹦出的想法就是求出这个二维数组的每一个子数组,虽然想法普通,时间复杂度高,却也不用考虑很多的特殊情况,出错的风险低了许多。
设计之初就是一个时间复杂度为n6的一个思路,第一层即最外层是关于起始位置的循环,第二层是关于终止位置的循环,最里层则是该子数组的自加求和,每层有两个for循环。
在一开始编写时,将循环时的值设为i,ii,iii,j,jj,jjj,运行时却失败了,花了两节课怎么也找不到错误,突然想起同伴的提醒:为什么不用i,i1,i2,j1,j1,j2,这样不是更容易看点,于是便将所有值该了过来,改到最后一个jjj值时,才发现,我是将“jjj”写成了“jj”,导致了程序的无限循环。
在研究错误的两节课里,经同伴提醒,想要减少时间复杂度,就是修改每层的for循环,减少一个,将i++写在for循环内,具体代码如下:
1 i = 0; 2 for(j = 0;j < n;j++) 3 { 4 i1 = i; 5 for(j1 =j;j1 < n;j1++) 6 { 7 i2 = i; 8 for(j2 = j;j2 <= j1;j2++) 9 { 10 sum += Shuzu[i2][j2]; 11 if((j2 == j1)&&(i2 < i1)) 12 { 13 i2++; 14 j2 = j; 15 } 16 else if(j2 == j1&&i2 == i1) 17 { 18 break; 19 } 20 } 21 if(max < sum) 22 { 23 max = sum; 24 shouL = i; 25 shouR = j; 26 weiL = i1; 27 weiR = j1; 28 } 29 sum = 0; 30 if(j1 == n -1 && i1 < m -1) 31 { 32 i1++; 33 j1 = j; 34 } 35 else if(j1 == n-1 && j1 == m - 1) 36 { 37 break; 38 } 39 } 40 if(j == n - 1 && j < m - 1) 41 { 42 i++; 43 j = 0; 44 } 45 else if(j == n - 1 && j == m - 1) 46 { 47 break; 48 } 49 }
能运行出来,可检验时发现有的运算结果是错误的,所以就先用了第一种方法。
这个程序还可以稍作改进,就是当存在最大子数组和相同的子数组时,将所有数组都输出,可以用数组来保存。
五、结对开发成员
刘双渤,刘洪阳
标签:
原文地址:http://www.cnblogs.com/little-clever/p/4412637.html