Java 河内塔楼与爪哇岛
我正在研究爪哇的河内塔问题。我选择使用堆栈作为钉子,除了移动方法外,其他方法都可以工作。我有规范和JUnit测试类,目前通过了7个测试中的6个,但移动测试失败。规格如下: 这是我的Java 河内塔楼与爪哇岛,java,stack,towers-of-hanoi,Java,Stack,Towers Of Hanoi,我正在研究爪哇的河内塔问题。我选择使用堆栈作为钉子,除了移动方法外,其他方法都可以工作。我有规范和JUnit测试类,目前通过了7个测试中的6个,但移动测试失败。规格如下: 这是我的Towers课程: package edu.metrostate.ics240.p2.towers; import java.util.Stack; public class Towers { private static final int DEFAULT_SIZE = 5; private s
Towers
课程:
package edu.metrostate.ics240.p2.towers;
import java.util.Stack;
public class Towers {
private static final int DEFAULT_SIZE = 5;
private static final int MAX_SIZE = 64;
private static final int MIN_PEG = 1;
private static final int MAX_PEG = 3;
private static Stack<Integer>[] tower = new Stack[4];
private int numOfRings;
public Towers(int n) {
if (n < 1 || n > MAX_SIZE)
throw new IllegalArgumentException(
String.format("Number of rings (%s) cannot be less than 1 or exceed 64 ", n));
numOfRings = n;
tower[1] = new Stack<Integer>();
tower[2] = new Stack<Integer>();
tower[3] = new Stack<Integer>();
for (int i = 1; i <= numOfRings; i++)
tower[1].push(i);
}
public Towers() {
numOfRings = DEFAULT_SIZE;
tower[1] = new Stack<Integer>();
tower[2] = new Stack<Integer>();
tower[3] = new Stack<Integer>();
for (int i = 1; i <= numOfRings; i++)
tower[1].push(i);
}
private static void pegCheck(int pegNumber){
if (pegNumber < MIN_PEG || pegNumber > MAX_PEG)
throw new IllegalArgumentException(
String.format("Peg number (%s) cannot be less than 1 or exceed 3 ", pegNumber));
}
public int getRingCount(int pegNumber) {
pegCheck(pegNumber);
switch (pegNumber) {
case 1:
if (tower[1].isEmpty())
return 0;
else
return tower[1].size();
case 2:
if (tower[2].isEmpty())
return 0;
else
return tower[2].size();
case 3:
if (tower[3].isEmpty())
return 0;
else
return tower[3].size();
default:
return 0;
}
}
public int getTopDiameter(int pegNumber) {
pegCheck(pegNumber);
switch (pegNumber) {
case 1:
if(getRingCount(1) > 0){
return tower[1].get(tower[1].peek() - tower[1].size());
}else
return 0;
case 2:
if(getRingCount(2) > 0){
return tower[2].get(tower[2].peek() - tower[2].size());
}else
return 0;
case 3:
if(getRingCount(3) > 0){
return tower[3].get(tower[3].peek() - tower[3].size());
}else
return 0;
default:
return 0;
}
}
public boolean move(int startPeg, int endPeg) {
pegCheck(startPeg);
pegCheck(endPeg);
Stack<Integer> startTower = tower[startPeg];
Stack<Integer> endTower = tower[endPeg];
if (getRingCount(startPeg) > 0 && endPeg != startPeg && getRingCount(endPeg) > 0 && getTopDiameter(startPeg) < getTopDiameter(endPeg)) {
int topRing = startTower.pop();
endTower.push(topRing);
return true;
}else
return false;
}
}
我想我知道我的问题在哪里。getTopDiameter()
的前提条件在getRingCount(pegNum)>0时返回顶环大小,但在堆栈为空或桩上没有环时返回0。由于tower[1]
是唯一使用环初始化的桩号,而其他两个桩号则不使用环初始化,getTopDiameter()
返回0,因为当前在tower[2]
和tower[3]
上没有环。在move()
方法中,一个先决条件要求getTopdiameter(startPeg)
小于getTopdiameter(endPeg)
但如果endPeg
初始化为0个环,因此为空,getTopdiameter(endPeg)
返回0,在这种情况下显然不小于1。我就是想不出这一点。非常感谢您的帮助,提前谢谢
更新
通过所有测试用例的修订代码:
package edu.metrostate.ics240.p2.towers;
import java.util.Stack;
public class Towers {
private static final int DEFAULT_SIZE = 5;
private static final int MAX_SIZE = 64;
private static final int MIN_PEG = 1;
private static final int MAX_PEG = 3;
@SuppressWarnings("unchecked")
private static Stack<Integer>[] tower = new Stack[4];
private int numOfRings;
public Towers(int n) {
if (n < 1 || n > MAX_SIZE)
throw new IllegalArgumentException(
String.format("Number of rings (%s) cannot be less than 1 or exceed 64 ", n));
numOfRings = n;
tower[1] = new Stack<Integer>();
tower[2] = new Stack<Integer>();
tower[3] = new Stack<Integer>();
for (int i = numOfRings; i >= 1; i--)
tower[1].push(i);
}
public Towers() {
numOfRings = DEFAULT_SIZE;
tower[1] = new Stack<Integer>();
tower[2] = new Stack<Integer>();
tower[3] = new Stack<Integer>();
for (int i = numOfRings; i >= 1; i--)
tower[1].push(i);
}
private static void pegCheck(int pegNumber) {
if (pegNumber < MIN_PEG || pegNumber > MAX_PEG)
throw new IllegalArgumentException(
String.format("Peg number (%s) cannot be less than 1 or exceed 3 ", pegNumber));
}
public int getRingCount(int pegNumber) {
pegCheck(pegNumber);
if (tower[pegNumber].isEmpty()) {
return 0;
} else
return tower[pegNumber].size();
}
public int getTopDiameter(int pegNumber) {
pegCheck(pegNumber);
if (getRingCount(pegNumber) > 0) {
return tower[pegNumber].get(tower[pegNumber].size() - 1);
}
return 0;
}
public boolean move(int startPeg, int endPeg) {
pegCheck(startPeg);
pegCheck(endPeg);
if (endPeg != startPeg) {
if (getRingCount(startPeg) > 0) {
if (getRingCount(endPeg) == 0 || getTopDiameter(startPeg) < getTopDiameter(endPeg)) {
int topRing = tower[startPeg].pop();
tower[endPeg].push(topRing);
return true;
}
}
}
return false;
}
}
包edu.metrostate.ics240.p2.towers;
导入java.util.Stack;
公共级塔楼{
私有静态最终int默认值_SIZE=5;
私有静态最终int MAX_SIZE=64;
私有静态最终int MIN_PEG=1;
专用静态最终int MAX_PEG=3;
@抑制警告(“未选中”)
私有静态堆栈[]塔=新堆栈[4];
私人国际货币基金组织;
公共塔楼(国际北){
如果(n<1 | | n>最大尺寸)
抛出新的IllegalArgumentException(
String.format(“环数(%s)不能小于1或超过64”,n));
numOfRings=n;
塔[1]=新堆栈();
塔[2]=新堆栈();
塔[3]=新堆栈();
对于(int i=numoring;i>=1;i--)
塔架[1]。推力(i);
}
公共塔楼(){
numOfRings=默认大小;
塔[1]=新堆栈();
塔[2]=新堆栈();
塔[3]=新堆栈();
对于(int i=numoring;i>=1;i--)
塔架[1]。推力(i);
}
专用静态空隙检查(int pegNumber){
如果(桩号<最小桩号|桩号>最大桩号)
抛出新的IllegalArgumentException(
字符串格式(“Peg编号(%s)不能小于1或超过3”,Peg编号);
}
公共整数getRingCount(整数编号){
pegCheck(pegNumber);
if(塔[pegNumber].isEmpty()){
返回0;
}否则
回流塔[pegNumber]。尺寸();
}
公共整数getTopDiameter(整数编号){
pegCheck(pegNumber);
如果(getRingCount(pegNumber)>0){
返回塔[pegNumber].get(塔[pegNumber].size()-1);
}
返回0;
}
公共布尔移动(int startPeg,int endPeg){
pegCheck(startPeg);
pegCheck(endPeg);
if(endPeg!=startPeg){
如果(getRingCount(startPeg)>0){
if(getRingCount(endPeg)==0 | | getTopDiameter(startPeg)
你说:
在move()方法中,一个先决条件要求getTopdiameter(startPeg)小于getTopdiameter(endPeg),但如果endPeg是用0个环初始化的,因此为空,则getTopdiameter(endPeg)返回0,在本例中显然不小于1
但是如果您阅读了您提供的图像中的先决条件-它说明getTopdiameter(startPeg)
小于getTopdiameter(endPeg)
如果endPeg
至少有一个环,那么将其作为您需要的条件写入
getRingCount(endPeg) > 0 && getTopdiameter(startPeg) < getTopDiamater(endPeg))
这是我在move()
中使用的条件:如果(getRingCount(startPeg)>0&&endPeg!=startPeg&&getRingCount(endPeg)>0&&getTopDiameter(startPeg)
是的,我现在看到了,对不起,它在你所有的条件和你描述它的方式中丢失了。是的,我很抱歉,我还是一个学生。仍然在学习所有的技巧。没问题,我现在明白问题所在了,我已经写了一些伪代码。看到我的编辑上面。我很感激,我会给它看一看,让你知道它是如何变成的。
getRingCount(endPeg) > 0 && getTopdiameter(startPeg) < getTopDiamater(endPeg))
if not same peg
if start peg has rings
if end peg is empty or (end peg has rings and diameters are compatible)
do move and return true
return false