Башня Ханоя с выводом. Как отобразить 1 вкладку для 1-го рекурсивного вызова, 2 вкладки для 2-го рекурсивного вызова и т. Д.? - PullRequest
2 голосов
/ 22 ноября 2010

Моя задача состояла в том, чтобы добавить несколько операторов печати, чтобы отобразить полный вывод Ханойская башня , чтобы увидеть и понять, что она делает за кулисами, вместо того, чтобы просто дать вам окончательный результат.

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)");

        }
    }
}

Вот что у меня есть в качестве вывода.Единственное, чего мне не хватает - это отступ .Мне нужно иметь 1 вкладку для первого уровня рекурсии, 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 ]

2 голосов
/ 22 ноября 2010

Простым способом является добавление параметра String с именем indent в doTowers, который будет добавлен ко всем выводам.Вызов из main передал бы пустую строку, каждый вызов в doTowers добавил бы пробелы или табуляции к этому параметру (то есть doTowers(indent+" ",...)).Вы бы изменили каждый System.out.println(...) на System.out.println(indent+...)

2 голосов
/ 22 ноября 2010

Самый простой, хотя, возможно, и не элегантный способ - просто передать рекурсивную глубину как интегральный аргумент вашей функции и увеличивать ее с каждым новым уровнем глубины:

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

....

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

Начните с 0для глубины в вашей основной функции.Затем просто напечатайте \t для каждого depth.

1 голос
/ 22 ноября 2010

Почему бы не передать дополнительный параметр, который вы увеличиваете с каждым рекурсивным вызовом?

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

и позже

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

Глубина покажет вам, сколько вкладок использовать. Первый звонок будет с глубиной 0.

1 голос
/ 22 ноября 2010

Конечно, счетчик хорошо это решает. Как вы справляетесь с рекурсией? Просто передайте это как параметр!

...