第9講 配列とfor文を利用して3次魔方陣を作ろう
第5話 2次順列方陣の生成プログラムの解説


解答コード再掲
public class A{
  public static void main(String args[]){
    f();
  }
  public static void f(){
    int i,j,k,l;
    int[][] a=new int[2][2];
    for(i=1;i<5;i++){
      a[0][0]=i;
      for(j=1;j<5;j++){
        a[0][1]=j;
        if(a[0][1]!=a[0][0]){
          for(k=1;k<5;k++){
            a[1][0]=k;
            if(a[1][0]!=a[0][0] && a[1][0]!=a[0][1]){
              for(l=1;l<5;l++){
                a[1][1]=l;
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
              }
            }
          }
        }
      }
    }
  }
}

頭が混乱しますね。解説は次話で。
if(a[1][0]!=a[0][0] && a[1][0]!=a[0][1]){
などは重複を防ぐためです。
簡単にトレースしてみましょう。
    int i,j,k,l;
    int[][] a=new int[2][2];
    for(i=1;i<5;i++){
      a[0][0]=i;
の最初のループで
1 2
1  
3 4
   

となります。ここは重複チェックが必要でなく、
2番目のセル(2番目のループに進みます。)
      for(j=1;j<5;j++){
        a[0][1]=j;
の最初のループによって

1 2
1 1
3 4
   

となります。

ここは2番目のセルなので、重複検査が必要で
        if(a[0][1]!=a[0][0]){
があるわけです。当然この検査を通り抜けることができませんので、
        if(a[0][1]!=a[0][0]){
          for(k=1;k<5;k++){
            a[1][0]=k;
            if(a[1][0]!=a[0][0] && a[1][0]!=a[0][1]){
              for(l=1;l<5;l++){
                a[1][1]=l;
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
              }
            }
          }
        }
は実行されず、次のループになり、

1 2
1 2
3 4
   

となります。これは重複チェック
        if(a[0][1]!=a[0][0]){
をクリアして
          for(k=1;k<5;k++){
            a[1][0]=k;
            if(a[1][0]!=a[0][0] && a[1][0]!=a[0][1]){
              for(l=1;l<5;l++){
                a[1][1]=l;
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
              }
            }
          }
の1番目のループが実行されまして、

1 2
1 2
3 4
1  

となる訳ですが、これは重複検査
            if(a[1][0]!=a[0][0] && a[1][0]!=a[0][1]){
をパスせず、次のループとなり

1 2
1 2
3 4
2  

となりますが、これも重複試験によってはねられ

1 2
1 2
3 4
3  

でようやく検査を通り抜け
              for(l=1;l<5;l++){
                a[1][1]=l;
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
              }
が実行されますが、最初の3回のループ

1 2
1 2
3 4
3 1 



1 2
1 2
3 4
3  2



1 2
1 2
3 4
3 3 

はいずれも重複チェック
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
に抵触してif文
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
は実行されません。
4度目の正直で

1 2
1 2
3 4
3 4 

はじめて重複試験
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
に合格して
if文
                if(a[1][1]!=a[0][0] && a[1][1]!=a[0][1] && a[1][1]!=a[1][0]){
                  System.out.print(a[0][0]);
                  System.out.print (" ");
                  System.out.print(a[0][1]);
                  System.out.println();
                  System.out.print(a[1][0]);
                  System.out.print (" ");
                  System.out.print(a[1][1]);
                  System.out.println();
                  System.out.println();
                }
が実行され、1個目の2次順列方陣がコマンドプロンプトに表示されます。
入門

以下のトレースは是非ご自分行ってください。

さて、次の課題です。いよいよ3次順列方陣に挑戦しましょう。
Java
(これはほんの1部です。362880通りもあるのですから。)


第4話へ 第6話へ

戻る

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