- 締切済み
n重のfor文にするには?
C言語の勉強をしはじめた者です。 よろしくお願いします。 「整数nを入力したときにn重for文にするにはどうしたらよいでしょうか?n個for文の中身の条件は、それぞれ異なりますが、nに依存した条件です。 」 たとえば、n=3と入力したとき、 for(i=1;i<=3;i++){ for(j=i+1;j<=4;j++){ for(k=j+1;j<=5;k++){ ... }}} また、 たとえば、n=5と入力したとき、 for(i=1;i<=3;i++){ for(j=i+1;j<=4;j++){ for(k=j+1;k<=5;k++){ for(l=k+1;l<=6;l++){ for(m=l+1;m<=7;m++)} ... }}}}} という感じに整数nを入力すると、その分、for文がでて、機能するようなプログラムはどうすればいいでしょうか? よければアドバイスください。 質問の仕方が下手くそですいません..
- みんなの回答 (10)
- 専門家の回答
みんなの回答
- Werner
- ベストアンサー率53% (395/735)
再帰呼び出しを使わないならこんな感じかな。 ------------------------------------------------------------ #include <stdio.h> int main(void){ int i,j,k,l,m; int nest=5; /*ネストの数*/ int cnt[10]={0,1}; /*ループカウンタ用。必要な要素数 = nest+1*/ int d=1; /*今いるところのネストの深さ。初期値1*/ while(cnt[0]<=0){ if(cnt[d]>d+2){ /* ループ継続条件を満たさないので外側のforループへ。外側のループカウンタ++ */ d--; cnt[d]++; } else if(d<nest){ /* 内側のforループへ。内側ループのカウンタ初期値は現在のループカウンタ+1 */ cnt[d+1]=cnt[d]+1; d++; } else if(d==nest){ /* 一番内側のforループ。やりたい処理とカウントアップ */ for(i=1;i<=nest;i++)printf("%2d\t",cnt[i]); printf("\n"); cnt[d]++; } } /*普通にネストした場合*/ printf("\n"); for(i=1;i<=3;i++){ for(j=i+1;j<=4;j++){ for(k=j+1;k<=5;k++){ for(l=k+1;l<=6;l++){ for(m=l+1;m<=7;m++){ printf("%2d\t%2d\t%2d\t%2d\t%2d\t\n",i,j,k,l,m); } } } } } return 0; }
- jacta
- ベストアンサー率26% (845/3158)
C言語で、ループの入れ子レベルを可変にするには、次の方法があります。 1. (既に回答が出ているように)再帰呼出しを使用する。 2. インタプリタを実装し、その上で動作するプログラムを記述する。 3. C言語のインタプリタを使用し、動的にソースファイルを編集しながら実行させる。 4. m4などのマクロ言語プロセッサを使用し、コンパイラのフロントエンドとする。 5. ソースコードジェネレータを自作する。 もし、C++であれば、上記の4.と同様のことを、C++のテンプレートを用いればできるような気がします。 まあ、いずれの方法を用いるにしても、決して簡単とはいえません。少なくとも、 > C言語の勉強をしはじめた者 には無理だと思いますので、別の方法を考えた方がよいでしょう。
- nerosuke
- ベストアンサー率33% (39/115)
No3です。 私の回答は完全にお門違いです。 失礼致しました。 単純にNに依存する違う条件のループを不定数N回、回したいのだと思ったんですけど不定数N個、回したいという質問のようですね。 今更ですが、皆さんの回答にあるように再帰処理が最良だと思います。 ただC言語学び始めで再帰処理はちょっと・・・って感じですね。 一応 階乗計算(再帰処理お約束)の参考URL貼っておきます。 個人的には質問者がどのような物を作成しているのか気になりますが。
- tatsu99
- ベストアンサー率52% (391/751)
もっとも、簡単でかつ確実な方法は、入力されるであろうnの値毎に、サーブルーチンをあらかじめ作成しておき、それを呼び出すことです。例えば、nが3,5,7と入力されることが、わかっているなら、そのnの値専用に、sub3,sub5,sub7のような関数をつくっておき、それを呼び出せばよいでしょう。 ただし、そうでは、なくで1つの関数でそれを実装したいということであれば、それを実現する一般的な方法はありません。私としては、どうしてこのような質問をされたのかということ自体に非常に興味があります。どうしてこのような質問をされたのか、差し支えなければ教えていただけませんでしょうか。
- nofutureforyou
- ベストアンサー率9% (25/277)
>C言語の勉強をしはじめた者です。 ということなら、 >n重for文にするにはどうしたらよいでしょうか? 普通そのようなことをする必要はありません。 まず、普通のCのやりかたを学びましょう。 Cプログラムを出力するプログラムを作ればそれは可能かと思いますが、今そういうことをやる必要は無いでしょう。 そういうのが好きなら lisp とかを学ぶのが吉かもしれませんが。
- sha-girl
- ベストアンサー率52% (430/816)
即席で作ったので、間違っているかもしれませんが やりたいことはこんな感じでしょうか? #include <stdio.h> #include <stdlib.h> int* p; int n = 5; void Fnc(int start , int end , int depth , int maxdepth ){ int i,nPrintCnt; int nowdep = maxdepth - depth; for( i = start ; i <= end ; i++ ){ p[nowdep] = i; if (depth > 0){ Fnc( i+1,end+1,depth-1,maxdepth); }else{ // ここでfor文内部の処理 for(nPrintCnt = 0 ; nPrintCnt < nowdep+1 ; nPrintCnt++ ){ printf("%2d",p[nPrintCnt]); } printf("\n"); } } } int main() { p = (int*)malloc(sizeof(int)*n); if (p){ Fnc( 1 , 3 , n-1 , n-1 ); } free(p); return 0; } n=5の結果 1 2 3 4 5 1 2 3 4 6 1 2 3 4 7 1 2 3 5 6 1 2 3 5 7 1 2 3 6 7 1 2 4 5 6 1 2 4 5 7 1 2 4 6 7 1 2 5 6 7 1 3 4 5 6 1 3 4 5 7 1 3 4 6 7 1 3 5 6 7 1 4 5 6 7 2 3 4 5 6 2 3 4 5 7 2 3 4 6 7 2 3 5 6 7 2 4 5 6 7 3 4 5 6 7 n=3の結果 1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>整数nを入力すると、その分、for文がでて 一般にC言語は、コンパイラ言語なので、LISPに代表されるような動的にシンタックス(文)を構成して評価することができません。 なので、プログラム中で入力された値で"for 文がでて"というのはできません。 そのようなCコンパイラで処理できるソースを出力するプログラムというのは、作れるかもしれません。そういう意味ですか? プログラムが動作中に入力された値で多重ループを構成するというのは、そのように実行できるようにプログラムを構成します。 見た目は質問文にあるようなfor文にはなりません。 #1,2の方の回答は、そのようなループを構成する方法として再帰呼び出しを使うと言っておられます。
- nerosuke
- ベストアンサー率33% (39/115)
for文の中でどのような処理をするかわかりませんが上にもうひとつ for被せればいいんじゃないでしょうか? n=5; for(i=0; i<n; i++) //N回分ループ { for() //ここの条件はNに依存するということなので工夫して下さい。 { } } これじゃ駄目でしょうか?
#1さんの書いたとおり再起呼び出しがいいと思いますが、 そもそも深いネストが必要なプログラムはアルゴリズム設計上よろしくない設計だと思います。
- Tacosan
- ベストアンサー率23% (3656/15482)
スタンダードなのは再帰的に関数を呼出すこと, かなぁ?