天天看點

螺旋矩陣問題

package com.spider.framwork;

import java.util.Scanner;

/**螺旋矩陣的demo(面向像我一樣數學不好,腦袋不大靈光的java初學者)
 * 思路:1、确定圈數的規律 2、确定方向的規律 3、确定每一圈的起始位置
 * 畫四個模型圖,從少到多,友善我們在其中摸索出資料遞增時的規律
 * 1 2
 * 4 3
 *
 * 1 2 3
 * 8 9 4
 * 7 6 5
 *
 *  1  2  3 4
 * 12 13 14 5
 * 11 16 15 6
 * 10  9 8  7
 *
 * 1  2  3  4  5
 * 16 17 18 19 6
 * 15 24 25 20 7
 * 14 23 22 21 8
 * 13 12 11 10 9
 */
public class MatrixDemo {
    private int startNum = 1;
    //矩陣的一條邊長,寫這麼長是因為矩陣這個單詞不認識,多寫幾遍,順便背個單詞
    private int matrixSideLen;
    private int turnsNumber;

    //矩陣的本體,一個邊長為變量的二維數組
    private int[][] matrix;

    //通過構造器獲得矩陣的大小和邊長
    public MatrixDemo(int matrixSideLen) {
        this.matrixSideLen = matrixSideLen;
        matrix = new int[matrixSideLen][matrixSideLen];
        /**
         * 根據獲得圈數的方法
         * 思路:通過矩陣的大小遞增,我們可以發現,圈數是邊長每加到奇數值加一圈,偶數不變,是以可以猜測規律為(matrixSide+1)/2
         */
        turnsNumber = (matrixSideLen + 1) / 2;
        createMatrix();
        for(int i = 0; i < matrixSideLen; i++){
            for(int m = 0; m < matrixSideLen; m++){
                if(matrix[i][m] < 10){
                    System.out.print(String.valueOf(matrix[i][m]).concat("  "));
                }
                else{
                    System.out.print(String.valueOf(matrix[i][m]).concat(" "));
                }
            }
            System.out.println();
        }
    }

    /**
     * 獲得目前圈數起始數值
     * @param turnIndex
     * @return
     */
    private int getCornerStartNumber(int turnIndex){
        int startIndex = 1;//設定初始值
        int sideNumber = matrixSideLen - 1;//因為每條邊有一個數字是重疊的,是以-1,周長值的1/4;
        //獲得目前圈數上層圈數的周長總和
        for(int i = 0; i<(turnsNumber - 1); i++){
            startIndex += sideNumber * 4;
            //因為每一層依次會少兩個數字
            sideNumber -= 2;
            continue;
        }
        return startIndex;

    }

    /**
     * 獲得目前圈每條邊數字個數
     */
    private int getSideNumberCount(int turnIndex){
        return (matrixSideLen - 1) -(turnIndex - 1) * 2;
    }

    /**
     * 生成目前圈
     * @param turnIndex
     */
    private void createConcurrentTurn(int turnIndex){
        int startIndex = getCornerStartNumber(turnIndex);//獲得目前圈起始值
        int sideNumberCount = getSideNumberCount(turnIndex);//獲得每條邊數字個數
        for(int i = 0; i < 4; i++){
            createSide(i, startIndex, sideNumberCount, turnIndex);
            continue;
        }
    }

    /**
     *
     * @param direction 方向
     * @param startIndex 起始值
     * @param sideNumberCount 邊值
     * @param turnsIndex 圈定位
     */
    private void createSide(int direction, int startIndex, int sideNumberCount, int turnsIndex){
        int cell = 0;//數組列坐标
        int row = 0;//數組行坐标
        switch (direction){
            //→方向:行不變,列遞增
            case 0:
                row  = turnsIndex - 1;
                cell = turnsIndex - 1;
                for(int i = 0; i < sideNumberCount; i++){
                    matrix[row][cell + i] = startNum;
                    startNum++;
                    continue;
                }
                break;
            //↓方向:列不變,行遞增
            case 1:
                row = turnsIndex - 1;
                cell = turnsIndex + sideNumberCount - 1;
                for(int i = 0; i < sideNumberCount; i++){
                    matrix[row + i][cell] = startNum;
                    startNum++;
                    continue;
                }
                break;
            //←方向:行不變,列遞減
            case 2:
                row = turnsIndex + sideNumberCount - 1;
                cell = turnsIndex + sideNumberCount - 1;
                for(int i = 0; i < sideNumberCount; i++){
                    matrix[row][cell - i] = startNum;
                    startNum++;
                    continue;
                }
                break;
            //↑方向:行遞減,列不變
            case 3:
                row  = turnsIndex + sideNumberCount - 1;
                cell = turnsIndex - 1;
                for(int i = 0; i < sideNumberCount; i++) {
                    matrix[row - i][cell] = startNum;
                    startNum++;
                    continue;
                }
                break;
        }
    }

    private void createMatrix(){
        for(int i = 0; i < turnsNumber; i++){
            int temp = i + 1;
            createConcurrentTurn(temp);
        }
        if(matrixSideLen % 2 == 1){
            matrix[matrixSideLen / 2][matrixSideLen / 2] = matrixSideLen * matrixSideLen;
        }
    }

    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        MatrixDemo matrixDemo = new MatrixDemo(scanner.nextInt());
    }
}