Java 實現任意N階幻方的構造


一、關於單偶數階幻方和雙偶數階幻方

(一)單偶數階幻方(即當n=4k+2時)

    任何4k+2 階幻方都可由2k+1階幻方與2×2方塊復合而成,6是此類型的最小階。

    以6階為例,可由3階幻方與由0,1,2,3組成的2×2的小方塊拼成一個6×6的大方塊復合而成。

       其中,3階幻方(洛書)如下圖1所示,

      

    (圖1)

 將每一單元格分成4等塊,各小塊的值與單元格的值相同,則行和、列和、對角和均為30,(見圖2),記為方陣M

(圖2)

用由0,1,2,3組成的2×2的小方塊拼成一個6×6的大方塊,使其行和、列和、對角和均為9,記為方陣N,(見圖3

(圖3)

6階幻方為方陣4M-N(見圖4

(圖4)

流程圖為:

(二)雙偶數階幻方(即當n=4k時)

如上圖所示,數字可分為有圈型和無圈型。對任意的4k階幻方,可將其等分為k*k個如上圖所示的4×4元組的結構。例如8階幻方可分成4個上述結構,無圈的按照“自左至右、自上至下”的順序把1~64個數填上,有圈的先放空;有圈的按照“自右至左,自下至上”的順序把1~64個數填上,無圈處暫放空。這樣即可生成8階幻方。

流程圖為:

二、具體代碼

package MagicSquare;

import java.util.Scanner;

import javax.sql.rowset.FilteredRowSet;

public class MagicSquare {
    
    
    //奇數幻方的實現:
    //盧培步法求奇數階幻方的函數,參數依次是儲存幻方的數組的名稱、幻方的階數,
    //標志位flag(為1表示主函數直接調用求奇數階幻方,為0表示SingleEven_Magic函數進行的調用)
    public static void  Odd_Magic(int array[][],int k ,int flag){
        int i=k,j=(k+1)/2,c=1;
        while (c<=k*k) {
            array[i][j]=c;
            if (c%k==0) {//若c是k的倍數,向上走
                i-=1;
            }
            else{//若c不是k的倍數,向右下走
                i+=1;
                j+=1;
                if (i>k) {
                    i=1;
                }
                if (j>k) {
                    j=1;
                }
            }
            c++;
        }
        if (flag==1) {
            outputArray(array);
        }
    }
    
    //雙偶數幻方:
    //即:階數能夠被4整除的幻方構造函數,參數依次是儲存幻方的數組的名稱、幻方的階數
    public static void  DoubleEven_Magic(int array[][],int k) {
        int i=1,j,c1=1,c2=k*k;
        while (i<k) {  //把4k階看作k*k 個4*4 的方塊,將主對角線和反對角線上的元素標記為 -1
            j=1;
            while (j<k) {
                array[i][j]=array[i+1][j+1]=array[i+2][j+2]=array[i+3][j+3]
                        =array[i][j+3]=array[i+1][j+2]
                        =array[i+2][j+1]=array[i+3][j]= - 1;
                j+=4;
            }
            i+=4;
        }
        
        for(i=1;i<=k;i++)
            for(j=1;j<=k;j++){
                
                //標記為0的進行正向依次賦值(java 在整型數組實例化時將所有元素初始化賦值為0)
                if (array[i][j]==0) {
                    array[i][j]=c1;
                }
                //否則,標記為-1 的進行反向依次賦值。
                else{
                    array[i][j]=c2;
                }
                c1++;
                c2--;
            }
            outputArray(array);//輸出幻方
        
    }
    
    
    //單偶數幻方:
      //即:階數被4除余2的幻方構造函數,參數依次是儲存幻方的數組的名稱、幻方的階數
    public static void  SingleEven_Magic(int array[][],int k) {
        int a[][]=new int[k+1][k+1];
        int b[][]=new int [k+1][k+1];
        int m[][]=new int [k/2+1][k/2+1];
        int i,j;
        
        Odd_Magic(m, k/2, 0);
        
        //由k/2奇數階幻方衍生出1比4的k階方陣M
        for(i=1;i<=k/2;i++)
            for(j=1;j<=k/2;j++){
                a[2*i-1][2*j-1]=a[2*i-1][2*j]=a[2*i][2*j-1]=a[2*i][2*j]=m[i][j];
            }
        
        //構造方陣N
        i=1;j=1;
        while (i<k) {
            j=1;
            while (j<k) {
                //上半部分A型 1230
                if (i<k/2||i==k/2&&(j==k/2+2||j==k/2-2)||i==k/2+2&&j==k/2) {
                    b[i][j]=1;
                    b[i][j+1]=2;
                    b[i+1][j]=3;
                    b[i+1][j+1]=0;
                }
                //左半部分C型 3102
                else if(i==k/2&&j<k/2-2){
                    b[i][j]=3;
                    b[i][j+1]=1;
                    b[i+1][j]=0;
                    b[i+1][j+1]=2;
                }
                //右半部分D型 2013
                else if(i==k/2&&j>k/2+2){
                    b[i][j]=2;
                    b[i][j+1]=0;
                    b[i+1][j]=1;
                    b[i+1][j+1]=3;
                }
                //6*6 核心中央和兩足 1203
                else if(i==k/2&&j==k/2||i==k/2+2&&(j==k/2+2||j==k/2-2)){
                    b[i][j]=1;
                    b[i][j+1]=2;
                    b[i+1][j]=0;
                    b[i+1][j+1]=3;
                }
                //下半部分B型 2103
                else {
                    b[i][j]=2;
                    b[i][j+1]=1;
                    b[i+1][j]=0;
                    b[i+1][j+1]=3;
                }
                j+=2;
            }
            i+=2;    
        }
        
        for(i=1;j<=k;i++)
        for(j=1;j<=k;j++){
            array[i][j]=4*a[i][j]-b[i][j];  //4*M-N 幻方形式
        }
        //outputArray(array);
        System.out.println();
        //兩種幻方輸出時中間間隔一行;
        for(i=1;i<=k;i++)
        for(j=1;j<=k;j++){
            array[i][j]=a[i][j]+(k/2)*(k/2)*b[i][j];   //M+(k/2)*(k/2)*N 幻方形式
           
        }
         outputArray(array);
    }
    
    //輸出幻方的函數,參數是儲存幻方的數組的名稱
    public static void outputArray (int array[][]) {
        for(int row=1;row<array.length;row++){
            for (int column = 1; column < array[row].length; column++) {
                System.out.printf("%5d",array[row][column]);
            }
            System.out.println();
        }
    }
    
    
    
    //測試函數
    public static void  main(String args[]) {
        int a[][];
        System.out.println("請輸入幻方階數:");
        Scanner input =new Scanner(System.in);
        int k=input.nextInt();
        a=new int[k+1][k+1];
        
        //階數為2的幻方不存在
        if (k==2) {
            System.out.println("不存在階數為2的幻方,請重新輸入!");
        }
        //奇數階幻方
        else if (k%2!=0) {
            Odd_Magic(a, k, 1);
        }
        //4k型幻方(雙偶數幻方)
        else if (k%4==0) {
            DoubleEven_Magic(a, k);
        }
        //4k+2型幻方(單偶數幻方)
        else {
            SingleEven_Magic(a, k);
        }
    }
}

 

三、結果截圖

 

 

(相關源碼詳見:https://github.com/shenxiaolinZERO/Resources/tree/master/Resources/Magic_Test

 

 

將每一單元格分成4等塊,各小塊的值與單元格的值相同,則行和、列和、對角和均為30,(見圖2),記為方陣M

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM