每当我的程序试图解决河内塔之谜时,我就会遇到这个奇怪的问题。每当它试图解决它时,它会将前两个光盘移动到末端极点(极点一直向右),但它会将剩余的光盘移回到起始极点。例如,如果我有一个有10个圆盘的河内塔,它将从起始杆移动前几个圆盘,但只有前2个圆盘使它到达终点杆。其余的圆盘最终回到第一个杆上。当它这样做时,它给我一个索引越界错误。我不确定它出了什么问题,任何帮助都将不胜感激。提前谢谢。
public class TowerOfHanoi
{
private int[] towerOne;
private int[] towerTwo;
private int[] towerThree;
private int discOne;
private int discTwo;
private int discThree;
/* Construct the Towers of Hanoi (3 towers) with aNumDisc
* on the first tower. Each tower can be identified by an
* integer number (0 for the first tower, 1 for the second
* tower, and 2 for the third tower). Each disc can be identified
* by an integer number starting from 0 (for the smallest disc)
* and (aNumDisc - 1) for the largest disc.
*/
public TowerOfHanoi(int aNumDiscs)
{
towerOne = new int[aNumDiscs];
for(int i = 0; i < aNumDiscs; i++){
towerOne[i] = aNumDiscs - 1 - i;
}
towerTwo = new int[aNumDiscs];
towerTwo[0] = aNumDiscs;
towerThree = new int[aNumDiscs];
towerThree[0] = aNumDiscs;
discOne = aNumDiscs;
discTwo = 0;
discThree = 0;
}
/* Returns an array of integer representing the order of
* discs on the tower (from bottom up). The bottom disc should
* be the first element in the array and the top disc should be
* the last element of the array. The size of the array MUST
* be the number of discs on the tower. For example, suppose
* the tower 0 contains the following discs 0,1,4,6,7,8 (from top
* to bottom). This method should return the array [8,7,6,4,1,0]
* (from first to last).
* @param tower the integer identify the tower number.
* @return an array of integer representing the order of discs.
*/
public int[] getArrayOfDiscs(int tower)
{
int[] tempTower;
if(tower == 0){
tempTower = new int[discOne];
for(int i = 0; i < discOne; i++){
tempTower[i] = towerOne[i];
}
return tempTower;
}
if(tower == 1){
tempTower = new int[discTwo];
for(int i = 0; i < discTwo; i++){
tempTower[i] = towerTwo[i];
}
return tempTower;
}
if(tower == 2){
tempTower = new int[discThree];
for(int i = 0; i < discThree; i++){
tempTower[i] = towerThree[i];
}
return tempTower;
}
return towerOne;
}
/* Gets the total number of discs in this Towers of Hanoi
* @return the total number of discs in this Towers of Hanoi
*/
public int getNumberOfDiscs()
{
return discOne+discTwo+discThree;
}
/* Gets the number of discs on a tower.
* @param tower the tower identifier (0, 1, or 2)
* @return the number of discs on the tower.
*/
public int getNumberOfDiscs(int tower)
{
if(tower == 0){
return discOne;
}
if(tower == 1){
return discTwo;
}
if(tower == 2){
return discThree;
}
return 0;
}
/* Moves the top disc from fromTower to toTower. Note that
* this operation has to follow the rule of the Tower of Hanoi
* puzzle. First fromTower must have at least one disc and second
* the top disc of toTower must not be smaller than the top disc
* of the fromTower.
* @param fromTower the source tower
* @param toTower the destination tower
* @return true if successfully move the top disc from
* fromTower to toTower.
*/
public boolean moveTopDisc(int fromTower, int toTower)
{
if((fromTower == 0 && discOne == 0)||(fromTower == 1 && discTwo == 0) || (fromTower == 2 && discThree == 0)){
return false;
}
if(fromTower == 0){
if(toTower == 1){
if(discTwo != 0&&towerOne[discOne-1]>towerTwo[discTwo-1]){
return false;
}
else{
towerTwo[discTwo]=towerOne[discOne-1];
towerOne[discOne-1] = 0;
discOne--;
discTwo++;
return true;
}
}
if(toTower == 2){
if(discThree != 0&&towerOne[discOne-1] > towerThree[discThree-1]){
return false;
}
else{
towerThree[discThree] = towerOne[discOne-1];
towerOne[discOne-1] = 0;
discOne--;
discThree++;
return true;
}
}
}
if(fromTower == 1){
if(toTower == 0){
if(discOne != 0&&towerTwo[discTwo-1]>towerOne[discOne-1]){
return false;
}
else{
towerOne[discOne]=towerTwo[discTwo-1];
towerTwo[discTwo-1] = 0;
discTwo--;
discOne++;
return true;
}
}
if(toTower == 2){
if(discThree!= 0&&towerTwo[discTwo-1] > towerThree[discThree-1]){
return false;
}
else{
towerThree[discThree] = towerTwo[discTwo-1];
towerTwo[discTwo-1] = 0;
discTwo--;
discThree++;
return true;
}
}
}
if(fromTower == 2){
if(toTower == 0){
if(discOne !=0 && towerOne[discOne-1]>towerTwo[discTwo-1]){
return false;
}
else{
towerOne[discOne]=towerThree[discThree-1];
towerThree[discThree-1] = 0;
discThree--;
discOne++;
return true;
}
}
if(toTower == 1){
if(discThree !=0&&towerThree[discThree-1] > towerTwo[discTwo-1]){
return false;
}
else{
towerTwo[discTwo] = towerThree[discThree-1];
towerThree[discThree-1] = 0;
discThree--;
discTwo++;
return true;
}
}
}
return false;
}
}
这是我用来运行上述程序的类。
import javax.swing.JFrame;
public class THSolverFrame
{
public static void main(String[] args) throws InterruptedException
{
int numberOfDiscs = 10;
TowerOfHanoi towers = new TowerOfHanoi(numberOfDiscs);
THComponent thc = new THComponent(towers);
JFrame frame = new JFrame();
frame.setTitle("Tower of Hanoi");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(thc);
frame.setVisible(true);
Thread.sleep(5000);
solveTower(towers, thc, numberOfDiscs, 0, 1, 2);
System.out.println("DONE!!!");
}
public static void solveTower(TowerOfHanoi towers, THComponent thc, int numberOfDiscs, int startPole, int tempPole, int endPole) throws InterruptedException
{
if(numberOfDiscs == 1) {
towers.moveTopDisc(startPole, endPole);
thc.repaint();
Thread.sleep(100);
}
else {
solveTower(towers, thc, numberOfDiscs - 1, startPole, endPole, tempPole);
towers.moveTopDisc(startPole, endPole);
thc.repaint();
Thread.sleep(100);
solveTower(towers, thc, numberOfDiscs - 1, tempPole, startPole, endPole);
}
}
}
答案 0 :(得分:0)
我在moveTopDisk()
方法中将其追溯到两行。第一个是这个:
if(fromTower == 2){
if(toTower == 0){
if(discOne !=0 && towerOne[discOne-1]>towerTwo[discTwo-1]){ <---- HERE
这里的第三个If语句试图访问towerTwo,它应该使用towerThree和discThree所以我把它更改为:
if (fromTower == 2) {
if (toTower == 0) {
if (discOne != 0 && towerOne[discOne - 1] > towerThree[discThree - 1]) {
以前的方式,代码试图从塔上拉出光盘而没有任何光盘并导致错误。在再次运行之后,我在同一区域内发现了另一个这样的拼写错误。 :
if(toTower == 1){
if(discThree !=0&&towerThree[discThree-1] > towerTwo[discTwo-1]){
第二个If语句的目标是discThree,它应该使用discTwo。
if(toTower == 1){
if(discTwo !=0&&towerThree[discThree-1] > towerTwo[discTwo-1]){
在这些更改之后,代码为我运行,没有错误。我之后唯一的问题是它无法解决这个难题!该算法无法解决3碟以上的任何问题。我用3,4,5和10尝试了它,它只解决了它3.用4和5,程序停止了,但不是一个获胜的配置,当我用10尝试它时,它只是设法洗牌前3个光盘并且永远不会出现解决方案(为了以防万一,我让它运行5分钟)。
TL; DR我唯一的建议是要小心复制/粘贴,注意你是否使用零索引,你应该再看看你的算法,看它是否能真正解决难题。我自己还没有写任何东西来做河内谜题,所以我不熟悉如何在代码中实现它。我确实看到你有这个想法。那就是为了解决n盘的难题,首先必须解决n-1盘问题。祝你好好继续工作!