河内的塔楼计划 - 柜台

时间:2015-04-04 21:32:24

标签: java counter joptionpane towers-of-hanoi

我正在做一个Tower Of Hanoi计划 - 在钉1上有3个钉子和一叠盘子,从最大到最小(底部最大,顶部最小)。你现在要做的是将所有磁盘从peg 1移动到peg 3,你可以使用peg 2作为其他磁盘的存储空间。到目前为止,我已经正确放置磁盘(每个磁盘正在正确移动),现在我需要按顺序创建一个计数器变量,以显示用户输入的特定数量的磁盘需要多少次移动。例如,3张光盘至少需要7次移动。

https://www.mathsisfun.com/games/towerofhanoi.html

你可以看到我有一些注释了一些Moves ++,但无论我放置计数器,它似乎永远不会起作用。

public class TowerOfHanoi

    {//open class

    public void Answer(int numOfDisks, String Peg1, String Peg2, String Peg3, int Moves)
    {//open public void Answer

        Moves++;

        if (numOfDisks == 1)
        {//open if

            //Moves++;      
            System.out.println("\nNumber of Moves so far: " + Moves + "\nMove disk on Peg " + Peg1 + " to Peg " + Peg3);

        }//close if

        else
        {//open else

            //Moves++;
            Answer(numOfDisks - 1, Peg1, Peg3, Peg2, Moves);
            System.out.println("\nNumber of Moves so far: " + Moves + "\nMove disk on Peg " + Peg1 + " to Peg " + Peg3);
            //Moves++;
            Answer(numOfDisks - 1, Peg2, Peg1, Peg3, Moves);

         }//close else

    }//close public void Answer

    public static void main (String[]args)
    {//open main

        TowerOfHanoi TOH = new TowerOfHanoi();  
        String numOfDisks = JOptionPane.showInputDialog(null, "Enter a number!");
        int NumberOfDisks = Integer.parseInt(numOfDisks);
        System.out.println("\nNumber of disks chosen: " + NumberOfDisks);
        int Moves = 0;
        TOH.Answer(NumberOfDisks, "1", "2", "3", Moves);

    }//close main

}//close TowerOfHanoi class

5 个答案:

答案 0 :(得分:0)

增加每次移动时移动,即在两个println语句中的每一个之前移动,因为那些代表一个移动。 接下来,您需要从Answers方法返回Moves。将return Moves放在方法的末尾。当您调用方法时,请执行Moves = Answer(numOfDisks - 1, Peg1, Peg3, Peg2, Moves);

答案 1 :(得分:0)

您面临的一个问题是您正在使用递归并将移动计数器推送到Answer的新调用而不返回任何内容。返回时,移动计数器将恢复其先前的值。

这可以通过引入一个成员变量从我的角度返回值或更好的解决方案来解决。将其从参数列表中删除,并使用公共成员。然后你可以在代码的末尾添加TOH.moves。

然后,您将获得一致的计数,并可以使用该展示位置,但如果不仔细查看您的代码,它似乎是正确的。

答案 2 :(得分:0)

为了将最底层(第n个)磁盘从p1移动到p3,首先需要将第n-1个磁盘从p1移动到p2(并清理)。然后将p1移动到p3,然后将其余部分从p2移动到p3。

从这个文字说明中可以明显看出,你只是真的在'#34;移动p1到p3"部分。这是您应该增加移动计数器的地方。

为了以紧凑的形式展示这一点,这里是河内塔的一个非常短的版本(考虑这是你的java程序的快速原型;)它还展示了如何使用函数的返回值来获取 - 这里移动列表 - 在您的情况下,您的柜台。

let rec hanoi n p1 p2 p3 acc =
    match n with
    | 0 -> acc
    | _ -> 
        hanoi (n-1) p1 p3 p2 acc
        @ [p1,p3]                   // this is where a move is added
        @ hanoi (n-1) p2 p1 p3 acc 

hanoi 3 1 2 3 [] |> List.length

为了让它更容易看到,这里的版本只计算:

let rec hanoi1 n p1 p2 p3 acc =
    match n with
    | 0 -> acc
    | _ -> 
        hanoi1 (n-1) p1 p3 p2 acc
        + 1                   // this is where a move is added
        + hanoi1 (n-1) p2 p1 p3 acc 

hanoi1 3 1 2 3 0

答案 3 :(得分:0)

我的两分钱: 您可以尝试迭代程序,因此处理计数器更容易。你可以take a look here,基于this iterative program的河内塔楼的可视化,证明可以用最少的步骤解决问题。

我知道它不在JAVA中,但你会发现移植程序并不太难。

答案 4 :(得分:0)

河内解决方案的非迭代塔

import java.util.Arrays;

public class TowerOfHanoi {

    private static int SIZE = 5;

    private class stack {

        stack(int size) {
            dataElements = new int[size];
        }
        int[] dataElements;

        int top = -1;

        private void push(int element) {
            dataElements[++top] = element;
        }

        private int pop() {
            if(top==-1) {
                return -1;
            }
            int topEle = dataElements[top];
            dataElements[top]=0;
            top --;
            return topEle;
        }

        private int top() {
            if(top==-1) {
                return -1;
            }
            return dataElements[top];
        }

        private boolean isEmpty() {
            return top == -1;
        }
    }

    public static void main(String[] args) {
        towerOfHanoi(SIZE);
    }

    private static void towerOfHanoi(int number) {
        initialize(number);
        if(number % 2 == 0) {
            solveEven(number);
        } else {
            solveOdd(number);
        }
    }

    private static int recentMoved = -1;

    private static stack source = new TowerOfHanoi().new stack(SIZE);
    private static stack intermediate = new TowerOfHanoi().new stack(SIZE);
    private static stack destination = new TowerOfHanoi().new stack(SIZE);

    private static void solveEven(int number) {

        while(destination.top < number-1) {
            if(!movePlates(source, intermediate, destination)) {
                if(!movePlates(intermediate,destination,source)) {
                    if(!movePlates(destination, source, intermediate)){
                        continue;
                    }
                }
            }
        }

    }



    private static boolean movePlates(stack from , stack dest1 ,stack dest2) {
        boolean movedPlate = false;
        if(from.top()== recentMoved) {
            return movedPlate;
        }
        if((!from.isEmpty()) && from.top()<(dest1.top()==-1?10000:dest1.top())) {
            dest1.push(from.pop());
            recentMoved=dest1.top();
            movedPlate = true;
        }
        else if((!from.isEmpty()) && from.top()<(dest2.top()==-1?10000:dest2.top())){
            dest2.push(from.pop());
            recentMoved=dest2.top();
            movedPlate = true;
        }
        if(movedPlate)
            display();
        return movedPlate;
    }

    private static void display() {
        Arrays.stream(source.dataElements).forEach(System.out::print);
        //.stream().fl.forEach(System.out::print);
        System.out.print("\t");
        Arrays.stream(intermediate.dataElements).forEach(System.out::print);
        System.out.print("\t");
        Arrays.stream(destination.dataElements).forEach(System.out::print);
        System.out.print("\n");
    }


    private static void initialize(int number) {
        for(int i=number;i>0;i--) {
            source.push(i);
        }
    }

    private static void solveOdd(int number) {
        while(destination.top < number-1) {
            if(!movePlates(source, destination, intermediate)) {
                if(!movePlates(destination,intermediate,source)) {
                    if(!movePlates(intermediate, source, destination)){
                        continue;
                    }
                }
            }
        }

    }

}