第9講 関数の再帰的使用
第6話 関数の再帰的使用によるn次順列生成解説その3

コード再掲
#include<iostream>
using namespace std;
void f(int g);
void h();
int x[15],n;
long cn;
void main(){
   cout<<"何次順列を生成しますか?"<<endl;
   scanf("%d",&n);
   cout<<endl;
   cn=0;
   f(0];
   cout<<n<<"次順列が"<<cn<<"個生成されました。"<<endl;
}
void f(int g){
   int i,j;
   for(
i=1;i<n+1;i++){
     x[g]=
i;
     if(
g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
     if(
g+1<n){
        f(
g+1);
     }
     else{
        h();
        cn++;
     }
     tobi:;
   }
}
void h(){
   for(char i=0;i<n;i++)cout<<x[i]<<" ";
   cout<<endl;
}
b

解説

 0
1 2 3

1個目の順列の作成表示に成功すると、f (2]は寿命を終えて、消滅し

 0
1 2

となります。f (1)のfor文のi++によって、

 0
1 3

となります。x[1]≠x[0]なので、チェック
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }

をクリアして
     if(g+1<n){
        f(
g+1);
     }
     else{
        h();
        cn++;
     }

が行われます。g=1ですから、g + 1 < n  は 1 + 1 < 3
で成り立ち、
        f (g + 1)
が呼び出され、セル番号2の世界の2回目の生誕となります。

 0
1 3

   for(=1;<n+1;++){
     x[g]=
;
によって、

 0
1 3 1

となります。残念ながら、x[2] = x[0] ですから
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
の1回目のループにおいてgoto tobi;によって
     if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
を飛び越し、f (2)のfor文のi++により、

 0
1 3 2

となります。x[2]≠x[0]、x[2]≠x[1]なので、
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
において2回とも跳躍はされず、
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
の実行となりますが、g=2ですから g + 1 < n は  2 + 1 < 3 で成り立ちませんので
     else{
        h();
        cn++;
     }
が実行され、2個目の順列c
が表示されることになります。
そして、for文のi++によって

 0
1 3 3

となりますが、x[2] = x[1]で
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
のj=1のとき、goto tobi;によって
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
が無視され、
f (
2)のすべての処理が終わり、
2回目のf (
2)の消滅となります。

 0
1 3

そして、f (1)も任務が終了して、消滅します。

 0
1

for文のi++によって、

 0
2

となりますが、g=0なので、
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
は無視されて、
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
の肯定の方が実施され、セル番号1の世界の2回目の誕生となります。

 0
2

となります。
   for(=1;<n+1;++){
     x[g]=
;
によって、

 0
2 1

となります。x[1]≠x[0]で、チェック
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
をクリアして、
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
の肯定の側が遂行され、セル番号2の世界の3回目の生成となります。

 0
2 1

   for(=1;<n+1;++){
     x[g]=;
によって、

 0
2 1 1

となります。 x[2] = x[1]
ですので
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
の2回目のループで跳躍が起き、
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
は実施されず、for文のi++によって

 0
2 1 2

今度は、 x[2] = x[0]で
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
1回目で跳躍が起き、
    if(g+1<n){
        f(g+1);
     }
     else{
        h();
        cn++;
     }
は実行されず、for文のi++によって

 0
2 1 3

x[2]≠x[0]、x[2]≠x[1]なので3度目の正直で
     if(g>0){
        for(j=0;j<g;j++){
          if(x[g]==x[j])goto tobi;
        }
     }
のチェックをクリアして
     else{
        h();
        cn++;
     }
の命令が行われ、3個目の順列d
が表示されます。

本日のトレースはここまで。これ以降のトレースは次話で。





第5話へ 第7話へ


a

魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ