zoukankan      html  css  js  c++  java
  • 求最小子数组之二维篇

    一、设计思路

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

    图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]+"	");
    32                 if(j == n - 1)
    33                 {
    34                     System.out.print("
    ");
    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] + "	");
    81                 if(j == weiR)
    82                 {
    83                     System.out.print("
    ");
    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

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

    五、结对开发成员

    刘双渤,刘洪阳

  • 相关阅读:
    Linux软件的卸载
    elasticsearch2.x插件之一:marvel(简介)
    elasticsearch2.x插件之一:kibana
    Jmeter简单测试elasticsearch服务器
    telnet
    koa 路由模块化(一)
    koa 应用生成器
    koa 基础(二十六)数据库 与 art-template 模板 联动 --- 编辑数据、删除数据
    koa 基础(二十五)数据库 与 art-template 模板 联动 --- 新增数据
    koa 基础(二十四)封装 DB 库 --- 新增数据、更新数据、删除数据
  • 原文地址:https://www.cnblogs.com/little-clever/p/4412637.html
Copyright © 2011-2022 走看看