第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;
}
解説
0 | 1 | 2 |
1 | 2 | 3 |
1個目の順列の作成表示に成功すると、f (2]は寿命を終えて、消滅し
0 | 1 |
1 | 2 |
となります。f (1)のfor文のi++によって、
0 | 1 |
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 | 2 |
1 | 3 | i |
for(i=1;i<n+1;i++){
x[g]=i;
によって、
0 | 1 | 2 |
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 | 2 |
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個目の順列
が表示されることになります。
そして、for文のi++によって
0 | 1 | 2 |
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 |
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 | 1 |
2 | i |
となります。
for(i=1;i<n+1;i++){
x[g]=i;
によって、
0 | 1 |
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 | 1 | 2 |
2 | 1 | i |
for(i=1;i<n+1;i++){
x[g]=i;
によって、
0 | 1 | 2 |
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 | 1 | 2 |
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 | 1 | 2 |
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個目の順列
が表示されます。
本日のトレースはここまで。これ以降のトレースは次話で。
第5話へ 第7話へ
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ