第19講 魔方陣汎用的生成プログラムVer.2
第4話 入力順構築プログラム解説
コード解説部分
  public static void z(){
    int i,j,p;
    int[][] a=new int[20][20];
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a[i][j]=n*n;
      }
    }

    for(i=0;i<n;i++){
      a[i][i]=i;
    }

    p=n;
    for(i=0;i<n;i++){
      if(a[i][n-1-i]==n*n){
        a[i][n-1-i]=p;
        p++;
      }
    }

    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        if(a[i][j]==n*n){
          a[i][j]=p;
          p++;
        }
      }
    }

    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        y[a[i][j]]=i;
        x[a[i][j]]=j;
      }
    }

  }
  public static void h(){ //動作確認のための表示メソッド 成功を確認した削除する
    int i,j;
    for(i=0;i<n*n;i++){
      m[y[i]][x[i]]=i;
    }

    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        if(m[i][j]<10){
          System.out.print(" "+m[i][j]+" ");
        }
        else{
          System.out.print(m[i][j]+" ");
        }
      }
      System.out.println();
    }

  }
色順に説明していきます。まず、最初のコード
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        a[i][j]=n*n;
      }
    }

では仮の番行が割り振られました。

16 16 16 16
16 16 16 16
16 16 16 16
16 16 16 16


4
25 25 25 25 25
25 25 25 25 25
25 25 25 25 25
25 25 25 25 25
4 25 25 25 25 25

今回仮の番号をn*nとしましたが、あり得ない番号であれば何でもよいのです。
とにかく正常でない番号を割り振りました。
この仮番号は何のために必要でしょうか。
もしこの仮の番号がないとすると、

4
4

と番号を割り振っていく内に


のセルが7と上書きされてしまいます。
上書きを防ぐために正常でない番号が割り振ってあります。
つまり、セルが正常でない場合にのみ書き換えるようにしたわけです。
    for(i=0;i<n;i++){
      a[i][i]=i;
    }

については重複の可能性がないので無条件に番号を割り振っています

4
25 25 25 25
25 25 25 25
25 25 25 25
25 25 25 25
4 25 25 25 25

次の、
    p=n;
pは割り振られる番号の役割を持っています。
さて、
    for(i=0;i<n;i++){
      if(a[i][n-1-i]==n*n){
        a[i][n-1-i]=p;
        p++;
      }
    }

には条件がついています。
異常な番号25(n*n)のときだけ、if文が実行されることになっています。
途中でi=2のときに正常な番号しますが、
このときは何もしないようにして上書きを防いでいます。
ですから、このfor分田終わった段階では

4
25 25 25
25 25 25
25 25 25 25
25 25 25
4 25 25 25

異常番号のときだけ、p++;が実行されるのでうまくいくのです。
また、p=n;の理由もお分かりですね。

    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        if(a[i][j]==n*n){
          a[i][j]=p;
          p++;
        }
      }
    }

も同様で番号が異常なときのみ上書きされるようになっています。
0,1,2,3,4,5,6,7,8は正常な番号ですから、上書きされず、

4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

① 各座標から番号へ が成功するのです。

さて、次の
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        y[a[i][j]]=i;
        x[a[i][j]]=j;
      }
    }

は逆対応の ② 番号から各座標へ を行っています。
例えば、16の対応をつけているわけです。

  public static void h(){ //動作確認のための表示メソッド 成功を確認した削除する
    int i,j;
    for(i=0;i<n*n;i++){
      m[y[i]][x[i]]=i;
    }

    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        if(m[i][j]<10){
          System.out.print(" "+m[i][j]+" ");
        }
        else{
          System.out.print(m[i][j]+" ");
        }
      }
      System.out.println();
    }

は番号付けが正常に行っているか確認のためです。




第3話へ 第5話へ

戻る

VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座

初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第2部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第3部