首页 > 代码库 > 打印螺旋矩阵数字

打印螺旋矩阵数字

明确了方阵数字是螺旋递增以后,发现每一个“口”字型的一圈数字正好闭合且连续递增。所以解题思路是由“口”字型的

递增依次向内嵌套。先填充最外层“口”字型的一圈数字,接着填充次外层……最后填充最内层的四个数。由一些较简单的画图可以

看出,层数的奇偶会影响到最内层的填充。当为奇数时,最内层只剩一个数字需要填充。所以奇数层需要单独考虑。

 

先是填充顶部的(n-1)个数字,接着由顶部的最后一个数字开始向下,填充右部的(n-1)个数字,接着是底部的(n-1)个和左部的(n-1)个,这样就填充了最外层的一圈“口”字型数字。(定一个静态的成员变量,从1开始,每填充一次,自增一次),依照同样的方法填充次外层,第三层……一直到偶数层的最内层。

 * 

填充的算法是:每一层未填充的个数是(n-2*l)个,n是总层数,l是当前层数,为了便于数组的计算,这里层数也是从0开始,

 * 即l=0时是第一层。每一轮填充都是从(l,l)开始的。←---字母l,不是数字1。   但是每一层都需要为邻边的填充留一个地方,比如填充顶部的时候,需要留出一个位置作为填充右部的开始,所以真正需要填充的个数是(n-2*l-1)。

 * 当层数为l时,每一边的起始坐标分别是(上,右,下,左):

 * (l,l)  

 * (l,n-l-1)

 * (n-1,n-1)

 * (n-1,l)

 * 

 * 当层数为偶数层的时候,恰好最后一层每一边填充一个数。当层数为奇数层的时候,最后一层只剩一个数未填充(n-2*l-1)=0,所以需要手动将最后一个数填充进方阵中。

 * 

 * 最后将填充好的方阵打印在控制台上。以上就是本题的思路和解决办法。


public static void main(String[] args) {
        System.out.println("输入方阵的层数(层数过大方阵的可读性会变差):");
        Scanner sc = new Scanner(System.in);
        //层数
        int n = sc.nextInt();
        //填充的数字,没填充一次自增一次 
        int var = 1;
        //方阵的中间,表示需要循环的次数,或者需要填充的“口”字个数。
        int limit = (int)Math.ceil(n/2.0) - 1;
        //定义一个n×n的矩阵来存储填充的数字
        int[][] metrix = new int[n][n];
        
        //嵌套的层数,循环limit次---limit个“口”
        for(int l=0;l<=limit;l++){
            /*填充顶部
             * 填充这一层时,i(横坐标)不变,j(纵坐标)递增,直到填充了(n-2*l-1)个数后退出这一层循环。
             */
            for(int i=l,j=i;j<l+(n-2*l-1);j++){
                metrix[i][j] = var++;
            }
            /*填充右边
             * 填充这一层时,j(纵坐标)不变,i(横坐标)递增,直到填充了(n-2*l-1)个数后退出这一层循环
             */
            for(int j=n-l-1,i=l;i<l+(n-2*l-1);i++){
                metrix[i][j] = var++;
            }
            /*填充底部
             * 填充这一层时,i(横坐标)不变,j(纵坐标)递减,直到填充了(n-2*l-1)个数后退出这一层循环。
             */
            for(int i=n-l-1,j=i;j>(n-l-1)-(n-2*l-1);j--){
                metrix[i][j] = var++;
            }
            /*填充左边
             * 填充这一层时,j(纵坐标)不变,i(横坐标)递减,直到填充了(n-2*l-1)个数后退出这一层循环
             */
            for(int i=n-l-1,j=l;i>(n-l-1)-(n-2*l-1);i--){
                metrix[i][j] =var++;
            }
        }
        //当层数是奇数时,以上算法并没有处理处于最中间的数,这里需要单独处理。
        if(n%2==1 && metrix[limit][limit] == 0){
            metrix[limit][limit] = var;
        }
        //打印
        printMetrix(metrix);
    }
    //打印矩阵,如果层数过高,需要将数字间的间隔加大(比如加更多的\t),否则可读性级差。
    public static void printMetrix(int[][] metrix){
        for(int i=0;i<metrix.length;i++){
            for(int j=0;j<metrix[i].length;j++){
                System.out.print(metrix[i][j] + "\t\t");
            }
            System.out.println();
        }
    }