黑马程序员技术交流社区

标题: 关于螺旋方阵打印,该方法同样适合非等边矩阵螺旋打印 [打印本页]

作者: 怪人长    时间: 2016-3-17 10:28
标题: 关于螺旋方阵打印,该方法同样适合非等边矩阵螺旋打印
本帖最后由 怪人长 于 2016-3-17 10:37 编辑

关于螺旋方阵打印问题,遇见这个问题先在稿纸上亲自模拟存放了一次方阵,由笔尖的游走为过程,所以我认为这种方法可以特别形象的描述该存放过程,并且该方法思想同样适用于非等边矩阵。下面提供我对该问题解决的分析和源代码,有什么可精简或者隐存潜在问题的地方还请广大“马”友指出来。代码仅供参考。
  1. /**
  2. *
  3. * 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
  4. * 1          2          3          4
  5. * 12         13         14         5
  6. * 11         16         15         6
  7. * 10         9          8          7
  8. */
  9. public class Demo01 {
  10.         /*
  11.          * 需求:如题。
  12.          *
  13.          * 分析:
  14.          * 1.创建一个int类型 n行 n列的二维数组Arr;
  15.          * 2.按照自然数螺旋存放进数组的方法将自然数存到Arr中;
  16.          * 3.打印出该二维数组;
  17.          *
  18.          * 自然数螺旋存放进数组的方法思路如下:
  19.          * 按照螺旋规则遍历该 n*n的二维数组,并在遍历的过程中将自然数存放进去。设定 Arr[h][l]代表第 h行第 l列,
  20.          * 首先从Arr[0][0]位置开始向右遍历,先假设当我们遍历完一行或者一列的时候,我们把这一行或列剔除出去,剩下
  21.          * 的元素组成一个新的矩阵,这样的话,每当遍历到矩阵四个角的时候,其以后的遍历规则就是固定的,比如当遍历到右上角
  22.          * 的时候,下一次遍历一定是往下遍历并剔除第一行,到右下角后要向左遍历并剔除最右边一列,到左下角后要向上遍历并
  23.          * 剔除最下一行,如此以来,每次都是在剩下的矩阵的边缘进行遍历,当遍历完最后一个位置时结束遍历。
  24.          * 那么要解决的问题就是如何确定是否为最后一个位置呢?
  25.          * 解决方法是:由原方阵定义最小行、最大行、最小列、最大列,每遍历完一行或一列之后剔除该行或列,如遍历完第一行
  26.          * 之后就让最小行的值加1,遍历完最后一列之后就让最大列的值减1,那么当剩下最后一个位置要遍历的时候,此时的最
  27.          * 小行和最大行相等、最小列和最大列相等。
  28.          */
  29.         
  30.         public static void main(String[] args) {
  31.                 int n = 10;
  32.                 int[][] Arr = new int[n][n];                  //定义个n*n的二维数组;
  33.                 generateArray(Arr, n);                  //对该数组进行螺旋存放自然数生成;
  34.                 print(Arr);                                 //打印输出该二维数组;
  35.         }
  36.         
  37.         //定义一个方法,用来对数组螺旋存放自然数生;
  38.         public static void generateArray(int[][] Arr, int n) {
  39.                
  40.                 int count = 1;                   //自然数;
  41.                
  42.                 int minh = 0;              //分别为最小行、最大行、最小列、最大列;
  43.                 int maxh = n-1;
  44.                 int minl = 0;
  45.                 int maxl = n-1;
  46.                
  47.                 int h = minh;              //分别是要遍历的行和列;
  48.                 int l = minl;
  49.         
  50.                 do {           //因为当满足最后一个位置条件时,该位置仍要遍历,所以使用do-while语句;
  51.                         if ((h == minh) && (l == minl)) {           //遍历位置为最小行最小列处,即左上角        
  52.                                 
  53.                                 if (!((h == 0) && (l == 0))) {      //判断是否是遍历的第一个位置,如果是第一个位置就直接遍历,否则就是刚遍历完最左一列,需要剔除最左列(最小列);
  54.                                         minl ++;
  55.                                 }
  56.                                 
  57.                                 for (int i = minl; i <= maxl; i++) {    //对向右遍历,直到当前矩阵最大列;
  58.                                         l = i;
  59.                                         Arr[h][l] = count;         //每遍历一个位置,就存放自然数;
  60.                                         count++;
  61.                                 }                                
  62.                         }else if ((h == minh) && (l == maxl)) {    //遍历位置到右上角的时候;
  63.                                 minh ++;                      //去除最上行(最小行);
  64.                                 
  65.                                 for (int i = minh; i <= maxh; i++) {   //向下遍历;
  66.                                         h = i;
  67.                                         Arr[h][l] = count;
  68.                                         count ++;
  69.                                 }
  70.                         }else if ((h == maxh) && (l == maxl)) {   //遍历到右下角;
  71.                                 maxl --;                    //去除最右列(最大列);
  72.                                 
  73.                                 for (int i = maxl; i >= minl; i--) {   //向左遍历;
  74.                                         l = i;
  75.                                         Arr[h][l] = count;
  76.                                         count ++;
  77.                                 }
  78.                         }else if ((h == maxh) && (l == minl)) {   //遍历到左下角;
  79.                                 maxh --;                  //去除最下行(最大行);
  80.                                 
  81.                                 for (int i = maxh; i >= minh; i--) {   //向上遍历;
  82.                                         h = i;
  83.                                         Arr[h][l] = count;
  84.                                         count ++;
  85.                                 }
  86.                         }               
  87.                 } while((maxh > minh) || (maxl > minl));  //当剩下的行数和列数都为1时,遍历该位置,结束遍历;
  88.         }
  89.         
  90.         //定义一个方法,用于将传入的二维数组打印出来;
  91.         public static void print(int [][] Arr) {
  92.                 for (int i = 0; i < Arr.length; i++) {
  93.                         for (int j = 0; j < Arr[i].length; j++) {
  94.                                 System.out.print(Arr[i][j] + "\t");
  95.                         }
  96.                         System.out.println();
  97.                 }
  98.         }

  99. }
复制代码



作者: 怪人长    时间: 2016-3-17 10:47
我还是新人贴,求罩,求罩




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2