Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 河内-爪哇计数塔_Java_Sorting_Count_Towers Of Hanoi - Fatal编程技术网

Java 河内-爪哇计数塔

Java 河内-爪哇计数塔,java,sorting,count,towers-of-hanoi,Java,Sorting,Count,Towers Of Hanoi,我正在测试河内塔项目。我已经得到了测量程序时间的帮助,但这不是我的教授想要的,他想要计算迭代次数。我无法下载,我需要程序运行的“移动总数”,但无法正确打印。你们能帮我吗?谢谢你 这是我使用的代码: 包堆栈溢出; 导入java.util.*; 公共级塔楼{ 公共静态int N; 公共静态堆栈[]整数=新堆栈[4]; 公共静态void main(字符串[]args){ 扫描仪输入=新扫描仪(System.in); 整数[1]=新堆栈(); 整数[2]=新堆栈(); 整数[3]=新堆栈(); Syst

我正在测试河内塔项目。我已经得到了测量程序时间的帮助,但这不是我的教授想要的,他想要计算迭代次数。我无法下载,我需要程序运行的“移动总数”,但无法正确打印。你们能帮我吗?谢谢你

这是我使用的代码:

包堆栈溢出;
导入java.util.*;
公共级塔楼{
公共静态int N;
公共静态堆栈[]整数=新堆栈[4];
公共静态void main(字符串[]args){
扫描仪输入=新扫描仪(System.in);
整数[1]=新堆栈();
整数[2]=新堆栈();
整数[3]=新堆栈();
System.out.print(“输入5个整数:”);
int num=input.nextInt();
N=num;
StackMove(num);
}
公共静态无效堆栈移动(int N){
对于(int d=N;d>0;d--)
整数[1]。推送(d);
PrintStack();
移动(N,1,2,3);
}
公共静态无效移动(int N,int a,int b,int c){
如果(N>0){
移动(N-1,a,c,b);
int d=整数[a].pop();
整数[c]。推送(d);
PrintStack();
移动(N-1,b,a,c);
}
}
公共静态void PrintStack(){
System.out.println(“A | B | C”);
System.out.println(“--------------”;
对于(int i=N-1;i>=0;i--){
字符串d1=“”,d2=“”,d3=“”;
试一试{
d1=String.valueOf(整数[1].get(i));
}捕获(例外e){
}
试一试{
d2=String.valueOf(整数[2].get(i));
}捕获(例外e){
}
试一试{
d3=String.valueOf(整数[3].get(i));
}捕获(例外e){
}
系统输出打印项数(“+d1+”|“+d2+”|“+d3”);
}
系统输出打印(“\n”);
}
}
输出应如下所示:

代码

import java.util.Stack;

import java.util.*;

public class TowersOfHanoiPrint {
    public static int N;
    public static Stack<Integer>[] integer = new Stack[4];

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        integer[1] = new Stack<>();
        integer[2] = new Stack<>();
        integer[3] = new Stack<>();
        System.out.print("Enter 5 integers: ");
        int num = input.nextInt();
        N = num;
        System.out.println("Number of moves: "+StackMove(num));
    }

    public static int StackMove(int N) {
        for (int d = N; d > 0; d--)
            integer[1].push(d);
        PrintStack();
        return move(N, 1, 2, 3);
    }

    public static int move(int N, int a, int b, int c) {
        if (N > 0) {
            int numberMovesA = move(N - 1, a, c, b);
            int d = integer[a].pop();
            integer[c].push(d);
            PrintStack();
            int numberMovesB = move(N - 1, b, a, c);
            return (numberMovesA + numberMovesB + 1);
        }
        return 0;
    }

    public static void PrintStack() {
        System.out.println("  A  |  B  |  C");
        System.out.println("---------------");
        for (int i = N - 1; i >= 0; i--) {
            String d1 = " ", d2 = " ", d3 = " ";
            try {
                d1 = String.valueOf(integer[1].get(i));
            } catch (Exception e) {
            }
            try {
                d2 = String.valueOf(integer[2].get(i));
            } catch (Exception e) {
            }
            try {
                d3 = String.valueOf(integer[3].get(i));
            } catch (Exception e) {
            }
            System.out.println("  " + d1 + "  |  " + d2 + "  |  " + d3);
        }
        System.out.print("\n");
    }
}

对于
n
项目,将
2
提升到
n
并减去
1

非主题评论 下面是一些关于代码的注释,这些注释并不能解决您的问题,但必须告诉您。(关于下面的主题评论)

标识符的命名 领养

例如:

  • 类名以大写字母开头,而方法名以小写字母开头(反之亦然)
  • 变量也以小写字母开头,只有常量是
    ALL\u大写
然后不要对变量使用单字母名称

为变量选择名称时,请从问题域中选取它们。
变量
整数
的含义是什么?
这里更合适的名称应该是
stacks
(注意复数形式的“s”),但不是因为它包含
Stack
类的对象,而是因为您正在对堆栈建模

您的(类)成员变量
N
会干扰某些方法的参数
N
。这里是唯一一个可以接受违反Java命名约定的地方:可以在成员变量前面加下划线(
\uu
)。这将有效地避免这种干扰

避免奇数球解决方案 这个双重标识符
N
在您的程序中导致两种不同的方法:

  • 您的某些方法访问成员变量
    N
  • 其他一些方法具有相同类型和相同名称的参数
对于任何程序,请选择其中一种访问方法

想象一下,如果您需要更改
N
,会发生什么情况。您的程序将开始表现出奇怪的行为,您将很难找到错误

不要将异常用作流控制 使用此代码,您可以在
d1
中保留空间,以防第一个堆栈没有足够的元素。您最好使用
if
语句来执行此操作:

String d1 = " ", d2 = " ", d3 = " ";
if( i < integer[1].size() ){
    d1 = String.valueOf(integer[1].get(i));
}
这里的问题是,该数组中有一个未使用的附加元素。更糟糕的是,它是数组中的第一个元素

Java有一些处理数组(和集合)的聪明例程,如果您的第一个数组元素像这样被忽略,这些例程将有问题,或者至少需要特殊处理

您可以使用另一种技术轻松解决这个问题:用常量替换幻数

您可以像这样在类中定义常量:

public class towers {
    private static final int STACK_ONE = 0;
    private static final int STACK_TWO = 1;
    private static final int STACK_TREE = 2;
        integer[STACK_ONE] = new Stack<>();
        integer[STACK_TWO] = new Stack<>();
        integer[STACK_TREE] = new Stack<>();
 //...
                d1 = String.valueOf(integer[STACK_ONE].get(i));
这将更改您的代码,如下所示:

public class towers {
    private static final int STACK_ONE = 0;
    private static final int STACK_TWO = 1;
    private static final int STACK_TREE = 2;
        integer[STACK_ONE] = new Stack<>();
        integer[STACK_TWO] = new Stack<>();
        integer[STACK_TREE] = new Stack<>();
 //...
                d1 = String.valueOf(integer[STACK_ONE].get(i));
在上一节中确定的位置,只需将一个添加到此新成员变量的当前值

额外参数和返回值 此解决方案由Dani提供

绕过一个反对象。 这在某种程度上类似于前面的解决方案,只是我们不需要返回一些东西。但是我们需要一个额外的类来完成这个任务。因此,这个解决方案对于这个简单的任务来说非常复杂,但我为记录添加了它

public class towers {
  private static class Counter{
     private int counter = 0;
     void increment(){ counter++;}
     int counted() { return counter; }
  }
  // ...
        Counter numberOfMoves= new Counter(num,);
        StackMove(num,numberOfMoves);
        System.out.println("Number of moves: "+ numberOfMoves.counted());
  // ...
    public static void StackMove(int N, Counter numberOfMoves) {
        for (int d = N; d > 0; d--)
            integer[1].push(d);
        PrintStack();
        move(N, 1, 2, 3, numberOfMoves);
    }
    public static void move(int N, int a, int b, int c, Counter numberOfMoves) {
        if (N > 0) {
            move(N - 1, a, c, b, numberOfMoves);
            int d = integer[a].pop();
            integer[c].push(d);
            PrintStack();
            move(N - 1, b, a, c, numberOfMoves);
            numberOfMoves.count();
        }
     }
  // ...

欢迎来到堆栈溢出!请拿着这本书,四处看看,仔细阅读,尤其是和“我的程序将运行,但无法正确打印。”这是什么意思?预期的输出是什么?你得到了什么?它应该打印并计算移动的总数。例如:5整数是总共31个动作。谢谢!得到了答案,尽管我怀疑它不会比我建议的算法运行得更快。我也会尝试@LewBloch:“我怀疑它不会比我建议的算法运行得更快。”看起来OP是个新手,性能是这里最不关心的问题。这一切都是因为OP了解解决方案。
        integer[STACK_ONE] = new Stack<>();
        integer[STACK_TWO] = new Stack<>();
        integer[STACK_TREE] = new Stack<>();
 //...
                d1 = String.valueOf(integer[STACK_ONE].get(i));
 public class towers
 {
    public static int N;
    public static int moveCounter = 0;
public class towers {
  private static class Counter{
     private int counter = 0;
     void increment(){ counter++;}
     int counted() { return counter; }
  }
  // ...
        Counter numberOfMoves= new Counter(num,);
        StackMove(num,numberOfMoves);
        System.out.println("Number of moves: "+ numberOfMoves.counted());
  // ...
    public static void StackMove(int N, Counter numberOfMoves) {
        for (int d = N; d > 0; d--)
            integer[1].push(d);
        PrintStack();
        move(N, 1, 2, 3, numberOfMoves);
    }
    public static void move(int N, int a, int b, int c, Counter numberOfMoves) {
        if (N > 0) {
            move(N - 1, a, c, b, numberOfMoves);
            int d = integer[a].pop();
            integer[c].push(d);
            PrintStack();
            move(N - 1, b, a, c, numberOfMoves);
            numberOfMoves.count();
        }
     }
  // ...