美文网首页
go-广度优先算法

go-广度优先算法

作者: phpdi | 来源:发表于2019-02-15 14:05 被阅读0次

    1.迷宫

    6 5
    0 1 0 0 0
    0 0 0 1 0
    0 1 0 1 0
    1 1 1 0 0
    0 1 0 0 1
    0 1 0 0 0
    

    2.思路

    • 用循环创建二维slice
    • 使用slice来实现队列
    • 用Fscanf读取文件
    • 对Point进行抽象

    3.代码

    package main
    
    import (
        "fmt"
        "os"
    )
    
    //读取迷宫数据,放入二维数组中
    func readMaze(filename string) [][]int {
        file, err := os.Open(filename)
        if err != nil {
            panic("文件不存在")
        }
        defer file.Close()
    
        var row, col int
    
        fmt.Fscanf(file, "%d %d", &row, &col)
    
        maze := make([][]int, row)
    
        for i := range maze {
            maze[i] = make([]int, col)
            for j := range maze[i] {
                fmt.Fscanf(file, "%d", &maze[i][j])
            }
        }
    
        return maze
    }
    
    type point struct {
        i, j int
    }
    
    //当前点的上,左边,下,右,
    var dirs = [4]point{
        {-1, 0}, {0, -1}, {1, 0}, {0, 1},
    }
    
    //当前点,移动
    func (p point) add(r point) point {
        return point{p.i + r.i, p.j + r.j}
    }
    
    //取出当前点对应的值
    func (p point) at(grid [][]int) (int, bool) {
        if p.i < 0 || p.i >= len(grid) {
            return 0, false
        }
    
        if p.j < 0 || p.j >= len(grid[0]) {
            return 0, false
        }
    
        return grid[p.i][p.j], true
    }
    
    //遍历迷宫
    func walk(maze [][]int, start, end point) ([][]int) {
        steps := make([][]int, len(maze))
    
        for i := range steps {
            steps[i] = make([]int, len(maze[0]))
        }
    
        //队列,存放将要探索的点
        Q := []point{start}
    
        for len(Q) > 0 {
            cur := Q[0]
            Q = Q[1:]
    
            //到终点了
            if cur == end {
                break
            }
    
            for _, dir := range dirs {
                next := cur.add(dir)
    
                //next 在maze 中的值为0才可以
                val, ok := next.at(maze)
                if !ok || val == 1 {
                    //没有值,或者撞墙,
                    continue
                }
    
                val, ok = next.at(steps)
                if !ok || val != 0 {
                    //探索过的位置,不再进行探索
                    continue
                }
    
                //回到原点,不进行探索
                if next == start {
                    continue
                }
    
                curSteps, _ := cur.at(steps)
    
                steps[next.i][next.j] = curSteps + 1
                Q = append(Q, next)
            }
    
        }
    
        return steps
    }
    
    func main() {
        maze := readMaze("maze/maze.in")
    
        steps := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
    
        for _, row := range steps {
            for _, val := range row {
                fmt.Printf("%3d ", val)
            }
            fmt.Print("\n")
        }
    }
    
    

    相关文章

      网友评论

          本文标题:go-广度优先算法

          本文链接:https://www.haomeiwen.com/subject/trqpeqtx.html