迷宮求解算法一直是算法學習的經典,實現天然也是多種多樣,包括動態規劃,遞歸等實現,這裏咱們使用窮舉求解,加深對棧的理解和應用java
起點座標爲(1,1),終點座標爲(8,8)
地圖打印在最下面
算法
class Position { private int px; private int py; public Position(int px, int py) { this.px = px; this.py = py; } public int getPx() { return px; } public void setPx(int px) { this.px = px; } public int getPy() { return py; } public void setPy(int py) { this.py = py; } }
move()
函數move函數分別向四個方向移動,而後將可行的path入棧.注意,這裏棧元素中每一個棧元素Position都是new出來的,棧中存的是reference,
注意看下面這種寫法:函數
currentPosition.setPy(currentPosition.getPy()+1); stacks.push(currentPosition);
這種寫法一度讓我陷入困惑,由於pop出來的Position都是同樣的,緣由你們可能應該明白了。。。學習
public void move() { if (moveRight()) { Position temp = new Position(currentPosition.getPx() + 1, currentPosition.getPy()); test.add(temp); stacks.push(temp); } else if (moveBottom()) { Position temp = new Position(currentPosition.getPx(), currentPosition.getPy() + 1); test.add(temp); stacks.push(temp); } else if (moveTop()) { Position temp = new Position(currentPosition.getPx(), currentPosition.getPy() - 1); test.add(temp); stacks.push(temp); } else if (moveLeft()) { Position temp = new Position(currentPosition.getPx() - 1, currentPosition.getPy()); test.add(temp); stacks.push(temp); } else { currentPosition = stacks.pop();//若當前位置四個方向都走不通,則將當前位置出棧,繼續遍歷上一節點 } }
class Position { private int px; private int py; public Position(int px, int py) { this.px = px; this.py = py; } public int getPx() { return px; } public void setPx(int px) { this.px = px; } public int getPy() { return py; } public void setPy(int py) { this.py = py; } } public class Maze { private final Position start;//迷宮的起點final private final Position end;//迷宮的終點final private ArrayList<String> footPrint;//足跡 private ArrayList<Position> test; private MyStack<Position> stacks;//自定義棧(也能夠用java.util中的Stack棧)若想了解MyStack的實現,能夠參考個人另外一篇博客 private Position currentPosition;//定義當前位置 public Maze() {//集合,棧的初始化工做 start = new Position(1, 1); end = new Position(8, 8); currentPosition = start; stacks = new MyStack<>(); test = new ArrayList<>(); } public static final int map[][] = //定義地圖10*10的方格 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 1, 0, 0, 0, 1, 0, 1}, {1, 0, 0, 1, 0, 0, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 1, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 0, 0, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, {1, 1, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}; public static void printMap() {//打印地圖 for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (map[i][j] == 1) System.out.print(" ■"); else System.out.print(" "); } System.out.println(); } } public boolean moveTop() {//上移 String s = currentPosition.getPx() + "" + (currentPosition.getPy() - 1); if ((map[currentPosition.getPx()][currentPosition.getPy() - 1] != 1) & !isArrived(s)) { footPrint.add(s); return true; } return false; } public boolean moveRight() {//右移 String s = (currentPosition.getPx() + 1) + "" + currentPosition.getPy(); if (map[currentPosition.getPx() + 1][currentPosition.getPy()] != 1 & !isArrived(s)) { footPrint.add(s); return true; } return false; } public boolean moveBottom() {//下移 String s = currentPosition.getPx() + "" + (currentPosition.getPy() + 1); if ((map[currentPosition.getPx()][currentPosition.getPy() + 1] != 1) & !isArrived(s)) { footPrint.add(s); return true; } return false; } public boolean moveLeft() {//左移 String s = (currentPosition.getPx() - 1) + "" + currentPosition.getPy(); if ((map[currentPosition.getPx() - 1][currentPosition.getPy()] != 1) & !isArrived(s)) { footPrint.add(s); return true; } return false; } public boolean isArrived(String position) {//判斷當前位置是否已經到打過 return footPrint.contains(position); } public void move() {//move函數分別向四個方向移動,而後將可行的path入棧 if (moveRight()) { Position temp = new Position(currentPosition.getPx() + 1, currentPosition.getPy()); test.add(temp); stacks.push(temp); } else if (moveBottom()) { Position temp = new Position(currentPosition.getPx(), currentPosition.getPy() + 1); test.add(temp); stacks.push(temp); } else if (moveTop()) { Position temp = new Position(currentPosition.getPx(), currentPosition.getPy() - 1); test.add(temp); stacks.push(temp); } else if (moveLeft()) { Position temp = new Position(currentPosition.getPx() - 1, currentPosition.getPy()); test.add(temp); stacks.push(temp); } else { currentPosition = stacks.pop();//若當前位置四個方向都走不通,則將當前位置出棧,繼續遍歷上一節點 } } public static void main(String[] args) { Maze m = new Maze(); m.footPrint = new ArrayList<>(); m.footPrint.add("11"); m.stacks.push(m.start); while (m.currentPosition.getPx() != 8 || m.currentPosition.getPy() != 8) { m.move(); } printMap(); System.out.println("下面是足跡,長度是:" + m.footPrint.size()); m.printFootPrint(); } public void printFootPrint() { for (int i = 0; i < footPrint.size(); i++) { System.out.print(footPrint.get(i) + ","); } System.out.println(); } }
你們可能會疑惑,爲何足跡是不連續的(例如:21,12)兩個位置是走不通的,是由於在path遍歷過程當中存在跳棧,既當前位置走不通便會將當前位置的Position出棧(stacks.pop),而後繼續上一節點遍歷。this
個人文章列表spa
Email:sxh13208803520@gmail.comcode