Пошаговая реализация состояний Ханойской башни Java

#java

#java

Вопрос:

Итак, я изначально застрял на том, как реализовать это пошаговое состояние в моем коде ханойской башни, я выяснил, как вывести его следующим образом

 Move one disk from 0 to 2
Move one disk from 0 to 1
Move one disk from 2 to 1
Move one disk from 0 to 2
Move one disk from 1 to 0
Move one disk from 1 to 2
Move one disk from 0 to 2
  

но я застрял на том, как реализовать пошаговое состояние башни, например :

  Initially:
 peg0: 3 2 1
 peg1: 0 0 0
 peg2: 0 0 0
 Step 1: Move disk1 from peg0 to peg2 resulting
 peg0: 3 2 0
 peg1: 0 0 0
 peg2: 1 0 0
 Step 2: Move disk2 from peg0 to peg1 resulting
 peg0: 3 0 0
 peg1: 2 0 0
 peg2: 1 0 0
 Step 3: Move disk1 from peg2 to peg1 resulting
 peg0: 3 0 0
 peg1: 2 1 0
 peg2: 0 0 0
 Step 4: Move disk3 from peg0 to peg2 resulting
 peg0: 0 0 0
 peg1: 2 1 0
 peg2: 3 0 0  
 Step 5: Move disk1 from peg1 to peg0 resulting
 peg0: 1 0 0
 peg1: 2 0 0
 peg2: 3 0 0
 Step 6: Move disk2 from peg1 to peg2 resulting
 peg0: 1 0 0
 peg1: 0 0 0
 peg2: 3 2 0
 Step 7: Move disk1 from peg0 to peg2 resulting
 peg0: 0 0 0
 peg1: 0 0 0
 peg2: 3 2 1
  

Вот код:

 public class Main
{
    // Creates a TowersOfHanoi puzzle and solves it.
    public static void main(String[] args)
    {
        TowersOfHanoi towers = new TowersOfHanoi(3);
        towers.solve();
    }
}
  

Код TowersOfHanoi

 public class TowersOfHanoi
{
    private int totalDisks;

    //-----------------------------------------------------------------
    // Sets up the puzzle with the specified number of disks.
    //-----------------------------------------------------------------

    public TowersOfHanoi(int disks)
    {
        totalDisks = disks;
    }

    //-----------------------------------------------------------------
    // Performs the initial call to moveTower to solve the puzzle.
    // Moves the disks from tower 1 to tower 3 using tower 2.
    //-----------------------------------------------------------------

    public void solve()
    {
        moveTower(totalDisks, 1, 3, 2);
    }

    //-----------------------------------------------------------------
    // Moves the specified number of disks from one tower to another
    // by moving a subtower of n-1 disks out of the way, moving one
    // disk, then moving the subtower back. Base case of 1 disk.
    //-----------------------------------------------------------------

    private void moveTower(int numDisks, int start, int end, int temp)
    {
        if (numDisks == 1)
        {
            moveOneDisk(start, end);
        }
        else
        {
            moveTower(numDisks-1, start, temp, end);
            moveOneDisk(start, end);
            moveTower(numDisks-1, temp, end, start);
        }
    }

    //-----------------------------------------------------------------
    // Prints instructions to move one disk from the specified start
    // tower to the specified end tower.
    //-----------------------------------------------------------------

    private void moveOneDisk(int start, int end)
    {
        System.out.println("Move one disk from "   start   " to "   end);
    }
}
  

Ответ №1:

Вы должны объявить новое поле private int step = 1; , чтобы вести подсчет шагов. Сохраняйте привязки в списке private List<LinkedList<Integer>> pegs= new ArrayList<>(3); Я использовал LinkedList для представления привязок, чтобы состояние привязок можно было легко распечатать.

Инициализируйте список привязок в конструкторе.

 for (int i = 0; i < 3; i  ) {
    pegs.add(new LinkedList<>());
}
  

Определите метод для печати состояния башен.

 private void printState() {
    int i = 0;
    for (LinkedList<Integer> peg : pegs) {
        System.out.print("peg"   i     ": ");
        for (int j = 0; j < 3; j  ) {
            try { 
                System.out.print(peg.get(j)   " ");
            }
            catch (Exception e) {
                System.out.print("0 ");
            }
        }
        System.out.println();
    }
}
  

Добавьте диски в peg0 в методе void solve() и распечатайте их. (Это также можно было бы сделать в конструкторе, но я думаю, что лучше сделать это в solve() ). Привязки должны быть пронумерованы от 0 до 2 при передаче фактических параметров для start , end и temp .

 LinkedList<Integer> peg0 = pegs.get(0);
peg0.add(3);
peg0.add(2);
peg0.add(1);
System.out.println("Initially :");
printState();
moveTower(totalDisks, 0, 2, 1);
  

В void moveOneDisk(int start, int end) выведите номер шага вместе с сообщением. Удалите последнюю привязку к диску start и добавьте ее к привязке end . Затем вызовите printState() .

 System.out.println("Step "   step     ": Move one disk from "   start   " to "   end);
pegs.get(end).add(pegs.get(start).removeLast());
printState();