迷宮求解算法(java版)

迷宮求解算法一直是算法學習的經典,實現天然也是多種多樣,包括動態規劃,遞歸等實現,這裏咱們使用窮舉求解,加深對棧的理解和應用java

定義Position類用於存儲座標點

起點座標爲(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();
    }
}

Paste_Image.png

你們可能會疑惑,爲何足跡是不連續的(例如:21,12)兩個位置是走不通的,是由於在path遍歷過程當中存在跳棧,既當前位置走不通便會將當前位置的Position出棧(stacks.pop),而後繼續上一節點遍歷。this

更多關於java的文章請戳這裏:(您的留言意見是對我最大的支持)

個人文章列表spa

Email:sxh13208803520@gmail.comcode

相關文章
相關標籤/搜索