【至急】再帰的なプログラムを非再帰的なものへ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
みなみ
記事: 2
登録日時: 9年前

【至急】再帰的なプログラムを非再帰的なものへ

#1

投稿記事 by みなみ » 9年前

再帰的なプログラムを非再帰的なものへと書き換えたいです。
途中まで挑戦していたのですが、うまくいきません。
関数recurAが元の関数で、この表記方法と同じ表記にするように関数recurBを書き換えたいです。
情けないながら未だ初心者知識しかなく、理解力に乏しい状況です。
そこで、大変申し訳ないのですがわかりやすい解説も頂ければ幸です。
何卒よろしくお願い申し上げます。
環境はLinuxです。
以下未完成のソースになります。

//再帰に対する理解を深めるための真に再帰的な関数3
#include <stdio.h>

/*真に再帰的な関数recurA*/

void recurA(int n)
{
if(n>0){
if(n%2 == 0) recurA(n/2);
else recurA(n-1);
printf("%d",n);
recurA(n-2);
}
}



/*再帰を除去した関数recurB*/
void recurB(int n){//0
int D,K;
D = K = 0;
D = K = n;


/*------第1判定------*/
Top:

if(n>1){

if(n%2==0){
n = n/2;
}

else {
n = n-1;
}
printf("%d",n);
goto Top;
}


/*------与えられたnを表示させる------*/
if(D==K)printf("%d",D);


/*------第2判定------*/
D = D-2;
n = D;

if(D>0){
printf("%d",D);
goto Top;
}
}





int main(void)
{
int x;

printf("整数を入力せよ : ");
scanf("%d",&x);

recurA(x);
printf("\n");

recurB(x);
printf("\n");

return 0;
}
最後に編集したユーザー みなみ on 2016年6月27日(月) 23:58 [ 編集 1 回目 ]

double-clutch.
記事: 21
登録日時: 9年前
住所: 近畿

Re: 再帰的なプログラムを非再帰的なものへ

#2

投稿記事 by double-clutch. » 9年前

今晩は double-clutch. と申します。
自分も初心者です。

ソースコードはタグ で囲ってください。
[ code] と [ /code] .... ここでは [ の直後に『半角スペース』を入れていますが、投稿される際は不要です。

あなたのcode
► スポイラーを表示
.... すいません、28行目の記述...

コード:

		Top:
とは、なんでしょうか??

上記のプログラムの実行結果は次になりました。
整数を入力せよ : 今回は 10 を入力しました。


1241251231101241281231612412
5421108421632142121

box
記事: 2002
登録日時: 14年前

Re: 再帰的なプログラムを非再帰的なものへ

#3

投稿記事 by box » 9年前

double-clutch. さんが書きました: .... すいません、28行目の記述...

コード:

		Top:
とは、なんでしょうか??
goto文の飛び先を示すラベルです。
コードの中に
goto Top;
っていう記載がありますよね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

みなみ
記事: 2
登録日時: 9年前

Re: 再帰的なプログラムを非再帰的なものへ

#4

投稿記事 by みなみ » 9年前

仰るとおり、Topはこのソースコードに置けるラベルとなっております。
goto Topに差し掛かったら自動でTop:の箇所まで戻り、そこから再び実行されます。

はいの整数10の場合上の関数Aが正しい表記なので、下のBを上と同じ表記にさせたいのです。
1241251231101241281231612412
5421108421632142121

個人的な見解としては、n-2まで実行した後のnがn-1の判定を通り抜けてしまっているものと思っています。
それとnのソートがうまくいっていないため、正しいnが求められていても、正しいならびかたになりません...。

box
記事: 2002
登録日時: 14年前

Re: 再帰的なプログラムを非再帰的なものへ

#5

投稿記事 by box » 9年前

みなみ さんが書きました: それとnのソートがうまくいっていないため、正しいnが求められていても、正しいならびかたになりません...。
nのソートって何でしょうか。
そもそも、再帰呼び出しを使った想定解を出力するコードにおいて
nをソートしているわけではなさそうに見えますので、
非再帰の場合においても同様なのではないですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

double-clutch.
記事: 21
登録日時: 9年前
住所: 近畿

Re: 【至急】再帰的なプログラムを非再帰的なものへ

#6

投稿記事 by double-clutch. » 9年前

みなみ さん


再帰処理では、仮引数の値を使用して何かしらの処理をさせるのですが、

この『仮引数の値』を使う順番が、『FILO (入れ後出し)』または、『FIFO(先入れ先出し)』で使用していきます。
つまり、データ構造『スタック』『キュー』に『仮引数の値』を『push』または『enq』し、
それらの情報を使いたいときに、『pop』または『deq』すればよいことになります。

具体的には、

コード:

void recurA(int n)
{
    if(n > 0){
        if(n % 2 == 0) recurA(n/2);
        else recurA(n - 1);
 
        printf("%d", n);
        recurA(n - 2);
    }
}
の『仮引数の値を使用して何かしらの処理をさせる』部分の

コード:

        printf("%d", n);
以前に呼び出しに使用した引数(== 次の関数での仮引数)が、『FILO (入れ後出し)』、
以後に呼び出しに使用した引数(== 次の関数での仮引数)が、『FIFO(先入れ先出し)』となります。


ここまで、偉そうに書いていますが自分は『スタック』までしか学習していません。
なので、『仮引数の値を使用して何かしらの処理をさせる』部分の、以前の記述しかでませんでした。

あと、出力形式が少し違いますがご了承ください。
► スポイラーを表示
みなみ さん の質問には答えきれていませんが、参考程度にどうぞ

かずま

Re: 【至急】再帰的なプログラムを非再帰的なものへ

#7

投稿記事 by かずま » 9年前

スタックを使えばよいのでは?

コード:

#include <stdio.h>

int s[10000], p;

void recurB(int n)
{
    while (1) {
        while (n > 0) {
            s[p++] = n;
            n = n & 1 ? n - 1 : n / 2;
        }
        if (p == 0) return;
        n = s[--p];
        printf(" %d", n);
        n -= 2;
    }
}

int main(void)
{
    int x;

    while (printf("整数を入力せよ : "), scanf("%d", &x) == 1) {
        recurB(x);
        printf("\n");
    }
    return 0;
}

かずま

Re: 【至急】再帰的なプログラムを非再帰的なものへ

#8

投稿記事 by かずま » 9年前

元のプログラムに合わせて、n & 1 を (n % 2 == 0) にしました。

コード:

#include <stdio.h>

void recurB(int n)
{
    static int s[10000], p;

    while (1) {
        while (n > 0) {
            s[p++] = n;
            n = (n % 2 == 0) ? n / 2 : n - 1;
        }
        if (p == 0) return;
        n = s[--p];
        printf(" %d", n);
        n -= 2;
    }
}

int main(void)
{
    int x;

    while (printf("整数を入力せよ : "), scanf("%d", &x) == 1) {
        recurB(x);
        printf("\n");
    }
    return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る