2

私の仕事は、一連の print ステートメントを追加して、ハノイの塔の完全な出力を表示し、最終結果を提供するだけでなく、舞台裏で何をしているのかを確認して理解することでした。

class TowersApp {
    static int nDisks = 3;
    public static void main(String[] args) {


        doTowers(nDisks, 'A', 'B', 'C');
    }

    public static void doTowers(int topN, char from, char inter, char to) {
        int i = 0;

        if(topN==1) {
            System.out.println("Enter (" + topN + " disk): " + "s=" + from + ", i=" + inter + ", d=" + to);
            System.out.println("Base case: move disk " + topN + " from " + from + " to "+ to);
            System.out.println("Return (" + topN + " disk)"); }
        else {
            System.out.println("Enter (" + topN + " disks): " + "s=" + from + ", i=" + inter + ", d=" + to);
            doTowers(topN-1, from, to, inter);
            System.out.println("Move bottom disk " + topN +
                    " from " + from + " to "+ to);
            doTowers(topN-1, inter, from, to);
            System.out.println("Return (" + topN + " disks)");

        }
    }
}

ここに私の出力としてあるものがあります。私が欠けているのはindentationだけです。第 1 レベルの再帰には 1 つのタブ、第 2 レベルの再帰には 2 つのタブが必要です。

現在の出力:

Enter (3 disks): s=A, i=B, d=C
Enter (2 disks): s=A, i=C, d=B
Enter (1 disk): s=A, i=B, d=C
Base case: move disk 1 from A to C
Return (1 disk)
Move bottom disk 2 from A to B
Enter (1 disk): s=C, i=A, d=B
Base case: move disk 1 from C to B
Return (1 disk)
Return (2 disks)
Move bottom disk 3 from A to C
Enter (2 disks): s=B, i=A, d=C
Enter (1 disk): s=B, i=C, d=A
Base case: move disk 1 from B to A
Return (1 disk)
Move bottom disk 2 from B to C
Enter (1 disk): s=A, i=B, d=C
Base case: move disk 1 from A to C
Return (1 disk)
Return (2 disks)
Return (3 disks)

望ましい出力:

Enter (3 disks): s=A, i=B, d=C
    Enter (2 disks): s=A, i=C, d=B
        Enter (1 disk): s=A, i=B, d=C
            Base case: move disk 1 from A to C
        Return (1 disk)
    Move bottom disk 2 from A to B
Enter (1 disk): s=C, i=A, d=B
...................................

関数に入った回数を「カウント」するには、ある種のカウンターが必要ですか? しかし、それは再帰でも可能ですか? この問題に対するもっと簡単な解決策がある場合、おそらく私は分析しすぎているのでしょうか?

4

4 に答える 4

2

indent簡単な方法は、すべての出力の先頭に追加される doTowers という名前の String パラメータを追加することです。main からの呼び出しは空の文字列を渡し、doTowers 内の各呼び出しはそのパラメーターにスペースまたはタブを追加します (つまりdoTowers(indent+" ",...))。System.out.println(...)それぞれを次のように変更しますSystem.out.println(indent+...)

于 2010-11-22T16:12:20.167 に答える
2

おそらく洗練されていないかもしれませんが、最も単純な方法は、再帰的な深さを関数に整数の引数として渡し、深さの新しいレベルごとにそれをインクリメントすることです。

public static void doTowers(int topN, char from, char inter, char to, int depth)

....

doTowers(..., depth + 1)
doTowers(..., depth + 1)

0メイン関数の for depthから始めます。次に、\tfor every を出力しdepthます。

于 2010-11-22T16:12:35.610 に答える
1

確かに、カウンターはこれをうまく解決します。再帰に沿ってどのように取得しますか?簡単に、パラメータとして渡します!

于 2010-11-22T16:10:35.643 に答える
1

再帰呼び出しごとにインクリメントする追加のパラメーターを渡さないのはなぜですか?

public static void doTowers(int topN, char from, char inter, char to, int depth)

そして後で

doTowers(topN-1, from, to, inter, depth+1);

深さは、使用するタブの数を示します。最初の呼び出しは深度 0 になります。

于 2010-11-22T16:26:04.857 に答える