算法导论:打印回旋数

  问题:打印输出逆时针螺旋矩阵,要求螺旋矩阵的阶数由用户输入。例如 n=4时,输出的螺旋矩阵如下:

  

  下面给出我的代码:  

 1 package org.warnier.zhang.exercises;
 2 
 3 public class Convolution {
 4     private int n;
 5     private int[][] array;
 6     private int number = 1;
 7 
 8     public Convolution(int n) {
 9         this.n = n;
10         array = new int[n][n];
11         init();
12     }
13 
14     private void init() {
15         for (int i = 0; i < n; i++) {
16             for (int j = 0; j < n; j++) {
17                 array[i][j] = 0;
18             }
19         }
20     }
21 
22     //逆时针方向回旋;
23     public void generateConvolutionNumber() {
24         //处理迭代“内圈”数字输出;
25         int a = 0;
26         int b = n -1 - a;
27         while (b >= a) {
28             //与正常的数组输出方向一致螺旋输出;
29             for (int i = a; i <= b; i++) {
30                 for (int j = a; j <= b; j++) {
31                     if (i != b && j == a) {
32                         array[i][j] = number++;
33                     }
34                     if (i == b && j != b) {
35                         array[i][j] = number++;
36                     }
37                 }
38             }
39             
40             //与正常的数组输出方向相反螺旋输出;
41             for (int i = b; i >= a; i--) {
42                 for (int j = b; j >= a; j--) {
43                     if (i != a && j == b) {
44                         array[i][j] = number++;
45                     }
46                     if (i == a && j != a) {
47                         array[i][j] = number++;
48                     }
49                 }
50             }
51             
52             a ++;
53             b = n -1 - a;
54         }
55         
56         //打个补丁:没能解决n为奇数的情况!(没有加上这句代码,中间的空格输出默认值0!)
57         if(n % 2 != 0){
58             array[n/2][n/2] = number;
59         }
60     }
61 
62     public void vprintf() {
63         for (int i = 0; i < n; i++) {
64             for (int j = 0; j < n; j++) {
65                 System.out.printf("%3d", array[i][j]);
66             }
67             System.out.println();
68         }
69     }
70 
71 }

  简要说明,和 的存在,是为了解决螺旋输出内圈的数字;下面的是测试代码:

 1 package org.warnier.zhang.exercises;
 2 
 3 public class ConvolutionTest {
 4 
 5     public static void main(String[] args) {
 6         Convolution convolution = new Convolution(5);
 7         convolution.generateConvolutionNumber();
 8         convolution.vprintf();
 9     }
10 
11 }
12 
13 结果:
14   1 16 15 14 13
15   2 17 24 23 12
16   3 18 25 22 11
17   4 19 20 21 10
18   5 6  7  8  9

  这是我的解决方法,主要是将回旋划分为从上到下,从左到右,从下到上,从右到左的四个方向分别处理,要注意后两个方向与正常的数组输出方向相反。这道算法题对学生党来说有点压力,但是掌握了能够写出好多好玩的东西,比如贪吃蛇。上面的算法只是一种可能的实现,欢迎读者贴上自己的代码,交流交流!

  根据读者回复,可以通过初始化将所有的数组元素赋值为 n * n 的方式,解决当 n 为奇数时,螺旋输出为默认值0的问题,下面贴上代码:

 1 package org.warnier.zhang.exercises;
 2 
 3 public class ConvolutionPro {
 4     private int n;
 5     private int[][] array;
 6     private int number = 1;
 7 
 8     public ConvolutionPro(int n) {
 9         this.n = n;
10         array = new int[n][n];
11         init();
12     }
13 
14     private void init() {
15         for (int i = 0; i < n; i++) {
16             for (int j = 0; j < n; j++) {
17                 //使用初始化赋值解决n为奇数的情况!
18                 array[i][j] = n * n;
19             }
20         }
21     }
22 
23     //逆时针方向回旋;
24     public void generateConvolutionNumber() {
25         //处理迭代“内圈”数字输出;
26         int a = 0;
27         int b = n -1 - a;
28         while (b >= a) {
29             //与正常的数组输出方向一致螺旋输出;
30             for (int i = a; i <= b; i++) {
31                 for (int j = a; j <= b; j++) {
32                     if (i != b && j == a) {
33                         array[i][j] = number++;
34                     }
35                     if (i == b && j != b) {
36                         array[i][j] = number++;
37                     }
38                 }
39             }
40             
41             //与正常的数组输出方向相反螺旋输出;
42             for (int i = b; i >= a; i--) {
43                 for (int j = b; j >= a; j--) {
44                     if (i != a && j == b) {
45                         array[i][j] = number++;
46                     }
47                     if (i == a && j != a) {
48                         array[i][j] = number++;
49                     }
50                 }
51             }
52             
53             a ++;
54             b = n -1 - a;
55         }
56     }
57 
58     public void vprintf() {
59         for (int i = 0; i < n; i++) {
60             for (int j = 0; j < n; j++) {
61                 System.out.printf("%3d", array[i][j]);
62             }
63             System.out.println();
64         }
65     }
66 
67 }

  当然,我们自然想到也可以顺时针螺旋输出,相应地调整上面两个for()的执行顺序即可。 

posted @ 2015-04-13 18:32  Warnier-zhang  阅读(1211)  评论(7编辑  收藏  举报