2010-11-22 2 views
2

Моя задача состояла в том, чтобы добавить кучу операторов печати, чтобы отобразить полный вывод Tower of Hanoi, чтобы увидеть и понять, что он делает за кулисами, вместо того, чтобы просто дать вам окончательный результат.Башня Ханоя отображения вывода. Как отобразить 1 вкладку для первого рекурсивного вызова, 2 вкладки для второго рекурсивного вызова и т. Д.?

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 
................................... 

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

ответ

2

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

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

.... 

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

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

+0

Это действительно глупый вопрос, но как бы напечатать \ t для глубины = 1, \ t \ t для глубины = 2, \ t \ t \ t для глубины = 3? – 2010-11-22 16:29:01

1

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

2

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

1

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

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

и позже

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

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