第15講 関数の再帰的呼び出し
第7話 関数の再帰的呼び出しによる順列作成の解説その4
      V(g=2の世界)i=2のとき、

これは、a[2]=a[1]なので
  if(g>0){
    for(j=0;j<g;j++){
      if(a[g]==a[j]){
        h=0;
                   break;
                 }
               }
              }

           によってhは0に書き換わり、
              if(h==1){
                if(g<n-1){
                  f(g+1);
                }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                    w+=L"\n";
                    s++;
                  }
                }
              }

           は実行されずに、

       
       の世界は終了となり、   

         


の世界に戻りますがすでにfor文の最後になっていて


の世界に戻ります。


  T(g=0の世界)i=1のとき、a[g]=i+1;によって、

となり、

  if(g>0){
    for(j=0;j<g;j++){
      if(a[g]==a[j]){
                   h=0;
                   break;
                 }
               }
              }

   はg=0なので無視され
              if(h==1){
                if(g<n-1){
                  f(g+1);
                }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                  w+=L"\n";
                  s++;
                }
              }
   が実行され、f(1)の世界

に飛び、




   for文の一回目の処理によって

となります。
a[1]≠a[0]なので
    for(j=0;j<g;j++){
      if(a[g]==a[j]){
        h=0;
                   break;
                 }
               }
    f(
2)が実行され、
    1回目のループで

となりますが、a[2]≠a[2]なので
    if(h==1){
       if(g<n-1){
         f(g+1);
     }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                    w+=L"\n";
                    s++;
                  }
                }
              } 
     は実行されず


となりますが、再びa[2]≠a[0]なので
    if(h==1){
       if(g<n-1){
         f(g+1);
                  }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                    w+=L"\n";
                    s++;
                  }
                }
              } 
      は無視されます。
      そして、3回目のループで

ようやく3個目の順列が完成します。
これでf(
2)は終了となり、f(1)の世界に戻り、


2回目のループで


でa[1]=a[0]となり、
    if(h==1){
       if(g<n-1){
         f(g+1);
                  }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                    w+=L"\n";
                    s++;
                  }
                }
              } 
    は実施されず、


a[1]≠a[0]
となり、f(
3)が呼ばれ


    1回目のループで

4個目の順列が完成します。
以後2回のループはいずれも
    for(j=0;j<g;j++){
      if(a[g]==a[j]){
        h=0;
                   break;
                 }

 によって、hが0に書き換わり

              if(h==1){
                if(g<n-1){
                  f(g+1);
                }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                  w+=L"\n";
                  s++;
                }
              }
     実行されません。
     以後



と動き5個目の順列が完成します。



さらに、


となり、6番目の順列が完成します。








と動いていきますが、いずれも
                for(j=0;j<g;j++){
                  if(a[g]==a[j]){
                    h=0;
                    break;
                  }
                }
によって、hは0に書き換わり
              if(h==1){
                if(g<n-1){
                  f(g+1);
                }
                else{
                  for(k=0;k<n;k++)w+=a[k].ToString()+L" ";
                  w+=L"\n";
                  s++;
                }
              }
は実行されず、6番目の順列が最後の順列だったことが分かります。

実に長い間お付き合い頂きましたが、ようやくトレースが終わりました。

4回の解説によって、呪文のように難しかった関数の再帰的呼び出しによる順列の作成のコードが見えてきたのではないでしょうか。
もし、まだ見えてない方は何度も熟読して下さい。
必ず氷解するものと確信します。

さて、第16講ではこの関数の再帰的呼び出しを使い3次と4次の魔方陣の作成に挑戦します。
そして、工夫を重ね5次6次7次8次9次10次と次数を高めていきます。
最終的には、

19 20 38 39 77 78 119 120 194 195 237 238 279 280 318 319 177 178
17 18 37 40 79 80 117 118 193 196 239 240 277 278 317 320 179 180
72 70 91 89 112 109 188 186 227 225 268 265 312 310 171 169 32 29
71 69 90 92 110 111 187 185 226 228 266 267 311 309 170 172 30 31
101 104 144 142 197 199 217 220 260 258 297 299 157 160 24 22 61 63
103 102 143 141 200 198 219 218 259 257 300 298 159 158 23 21 64 62
135 136 210 211 249 250 271 272 290 291 149 150 11 12 50 51 93 94
133 134 209 212 251 252 269 270 289 292 151 152 9 10 49 52 95 96
204 202 243 241 284 281 324 322 163 161 4 1 44 42 83 81 124 121
203 201 242 244 282 283 323 321 162 164 2 3 43 41 82 84 122 123
229 232 276 274 313 315 173 176 36 34 53 55 73 76 116 114 189 191
231 230 275 273 316 314 175 174 35 33 56 54 75 74 115 113 192 190
263 264 302 303 165 166 27 28 66 67 105 106 127 128 182 183 221 222
261 262 301 304 167 168 25 26 65 68 107 108 125 126 181 184 223 224
296 294 155 153 16 13 60 58 99 97 140 137 216 214 235 233 256 253
295 293 154 156 14 15 59 57 98 100 138 139 215 213 234 236 254 255
145 148 8 6 45 47 85 88 132 130 205 207 245 248 288 286 305 307
147 146 7 5 48 46 87 86 131 129 208 206 247 246 287 285 308 306

といった、18次魔方陣にも挑戦していきます。


ですが、その前にDataGridViewによってソフトを改良していきましょう。



第11講第6話へ
 第12講第1話へ 第14講第10話へ 第15講第6話へ 第15講第8話へ

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