码迷,mamicode.com
首页 > 编程语言 > 详细

求最小子数组之二维篇

时间:2015-04-09 23:29:04      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

一、设计思路

  求出该二维数组的所有子数组,先确定一个位置为起点,然后向右下方依次以此起点为始的所有子数组,技术分享

图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     }
View Code

三、实验结果
技术分享

图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         }    
View Code

能运行出来,可检验时发现有的运算结果是错误的,所以就先用了第一种方法。
  这个程序还可以稍作改进,就是当存在最大子数组和相同的子数组时,将所有数组都输出,可以用数组来保存。

五、结对开发成员

刘双渤,刘洪阳

技术分享

求最小子数组之二维篇

标签:

原文地址:http://www.cnblogs.com/little-clever/p/4412637.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!