java使用棧解迷宮問題
阿新 • • 發佈:2018-11-27
- 迷宮求解
- 從當前入口出發,順某一方向前進,若則走通,則繼續走,否則沿原路退回,換一個方向繼續走,直到到達終點或者所有的可能的通路都走過為止
- 需要一個後進先出的結構來儲存入口到當前位置的路徑,這個結構就是棧
關鍵點在於:要判斷一個位置 ,是否可通。 可通是指,可以通過,且之前沒有來過
package stack.demo; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * 用java提供的stack實現 */ public class MazePathStack { static class Spath { //行走的單位格子 private int x; private int y; private int di; //方向 0 1 2 3 表示右 下 左 上 public Spath(int x, int y, int di) { this.x = x; this.y = y; this.di = di; } @Override public boolean equals(Object obj) { if (super.equals(obj)) { return true; } if (obj instanceof Spath) { if ((((Spath) obj).x == this.x) && (((Spath) obj).y == this.y)) { return true; } else { return false; } } else { return false; } } } private static int[][] mg = MazePathStack.creatMG();//初始化時候生成迷宮 private static Stack<Spath> spathStack = new Stack();//路徑棧 public static void main(String[] args) { Spath spath = new Spath(0, 1, 0); //初始座標為入口 (0,1)方向為向右 do { if (isPass(spath)) { //判斷該座標能否通行 //判斷該座標是否是終點 if (isEnd(spath)) { spathStack.push(spath); System.out.println("到達終點,座標為:" + "(" + spath.x + "," + spath.y + ")"); System.out.println("路徑為"); printAll(); return; } //判斷該座標是否已經來過 if (isRecord(spath)) { //來過 則放棄棧中最新的座標 後退一格,換個方向重試 spathStack.pop(); spath = spathStack.peek(); spath = next(spath, false);//繼續下一步 換個方向 } else { //沒有來過 壓入棧中 記錄下來 spathStack.push(spath); spath = next(spath, true); //繼續下一步 沿原來方向 } } else { spath = spathStack.peek(); //後退一步 spath = next(spath, false);//換個方向 繼續下一步 } } while (!spathStack.empty()); } private static void printAll() { //列印路徑 List<Spath> spaths=new ArrayList<>(); while(!spathStack.empty()){ spaths.add(spathStack.pop()); } for (int i = spaths.size()-1; i >=0 ; i--) { System.out.println("("+spaths.get(i).x+","+spaths.get(i).y+")"); } } private static Spath next(Spath spath, boolean status) { if (status) { //繼續沿著原來方向 return SpathNext(spath); } else { //換方向 spath.di++; return SpathNext(spath); } } private static Spath SpathNext(Spath spath) { Spath spathNew = new Spath(spath.x, spath.y, 0);//生成新的路徑節點 新的節點方向需要重置 //方向 0 1 2 3 表示右 下 左 上 if (spath.di == 0) { //向右走 spathNew.y++; } if (spath.di == 1) { //向下走 spathNew.x++; } if (spath.di == 2) {//向左走 spathNew.y--; } if (spath.di == 3) {//向上走 spathNew.x--; } if (spathNew.x>=0&&spathNew.x<5&&spathNew.y>=0&&spathNew.y<10){ return spathNew; } return null; } private static Boolean isEnd(Spath spath) { if (spath.x == 4 && spath.y == 4) { return Boolean.TRUE; } else { return Boolean.FALSE; } } private static Boolean isRecord(Spath spath) { return spathStack.contains(spath); } private static Boolean isPass(Spath spath) { if (spath==null){ return Boolean.FALSE; } if (mg[spath.x][spath.y] == 1) { return Boolean.TRUE; } else { return Boolean.FALSE; } } public static int[][] creatMG() { //建立一個迷宮 int mg[][] = new int[5][10]; //建立正確的路徑,值為1表示可以通過 mg[0][1] = 1; mg[1][1] = 1; mg[2][1] = 1; mg[2][2] = 1; mg[3][2] = 1; mg[3][3] = 1; mg[3][4] = 1; mg[4][4] = 1; //建立干擾路徑 mg[0][2] = 1; mg[0][3] = 1; mg[0][4] = 1; mg[1][4] = 1; mg[1][5] = 1; mg[1][6] = 1; mg[2][6] = 1; for (int i = 0; i < 5; i++) { for (int j = 0; j < 10; j++) { System.out.print(mg[i][j]); } System.out.println(); } System.out.println(); return mg; } }
輸出如下:
0111100000
0100111000
0110001000
0011100000
0000100000
到達終點,座標為:(4,4)
路徑為
(0,1)
(1,1)
(2,1)
(2,2)
(3,2)
(3,3)
(3,4)
(4,4)