Google资深工程师深度讲解Go语言-迷宫的广度优先搜索(十二)

举报
lxw1844912514 发表于 2022/03/27 00:26:18 2022/03/27
【摘要】 一.广度优先算法 为爬虫实战项目做好准备应用广泛,综合性强面试常见 探索顺序: 上左下右 节点三种状态: 已经发现,但没有探索过 已经发现,并探索完成没有发现 结束条件:(1)走到终点  (2)走到队列为空 maze.go读取文件 package main import ( "fmt" "os") func...

一.广度优先算法

  • 为爬虫实战项目做好准备
  • 应用广泛,综合性强
  • 面试常见

探索顺序: 上左下右

节点三种状态:

  1. 已经发现,但没有探索过 
  2. 已经发现,并探索完成
  3. 没有发现

结束条件:(1)走到终点  (2)走到队列为空

maze.go读取文件


  
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func readMaze(filename string) [][]int {
  7. file, err := os.Open(filename)
  8. if err != nil {
  9. panic(err)
  10. }
  11. var row, col int
  12. fmt.Fscanf(file, "%d %d", &row, &col)
  13. maze := make([][]int, row)
  14. for i := range maze {
  15. maze[i] = make([]int, col)
  16. for j := range maze[i] {
  17. fmt.Fscanf(file, "%d", &maze[i][j])
  18. }
  19. }
  20. return maze
  21. }
  22. func main() {
  23. maze:=readMaze("maze/maze.in")
  24. for _,row:= range maze{
  25. for _,val:=range row {
  26. fmt.Printf("%d ",val)
  27. }
  28. fmt.Println()
  29. }
  30. }

maze.in文件


  
  1. 6 5
  2. 0 1 0 0 0
  3. 0 0 0 1 0
  4. 0 1 0 1 0
  5. 1 1 1 0 0
  6. 0 1 0 0 1
  7. 0 1 0 0 0

广度优先算法代码


  
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. type point struct {
  7. i, j int
  8. }
  9. var dirs = [4]point{
  10. {-1, 0}, {0, -1}, {1, 0}, {0, 1}}
  11. func (p point) add(r point) point {
  12. return point{p.i + r.i, p.j + r.j}
  13. }
  14. func (p point) at(grid [][]int) (int, bool) {
  15. if p.i < 0 || p.i >= len(grid) {
  16. return 0, false
  17. }
  18. if p.j < 0 || p.j >= len(grid[p.i]) {
  19. return 0, false
  20. }
  21. return grid[p.i][p.j], true
  22. }
  23. func walk(maze [][]int, start, end point)[][]int {
  24. steps := make([][]int, len(maze))
  25. for i := range steps {
  26. steps[i] = make([]int, len(maze[i]))
  27. }
  28. //队列
  29. Q := []point{start}
  30. for len(Q) > 0 {
  31. cur := Q[0]
  32. Q = Q[1:]
  33. if cur==end {
  34. break
  35. }
  36. for _, dir := range dirs {
  37. next := cur.add(dir)
  38. //maze at next is 0
  39. //and steps at next is 0
  40. //and next !=start
  41. val, ok := next.at(maze)
  42. if !ok || val == 1 {
  43. continue
  44. }
  45. val, ok = next.at(steps)
  46. if !ok || val != 0 {
  47. continue
  48. }
  49. if next == start {
  50. continue
  51. }
  52. curSteps, _ := cur.at(steps)
  53. steps[next.i][next.j] = curSteps + 1
  54. Q = append(Q, next)
  55. }
  56. }
  57. return steps
  58. }
  59. func readMaze(filename string) [][]int {
  60. file, err := os.Open(filename)
  61. if err != nil {
  62. panic(err)
  63. }
  64. var row, col int
  65. fmt.Fscanf(file, "%d %d", &row, &col)
  66. maze := make([][]int, row)
  67. for i := range maze {
  68. maze[i] = make([]int, col)
  69. for j := range maze[i] {
  70. fmt.Fscanf(file, "%d", &maze[i][j])
  71. }
  72. }
  73. return maze
  74. }
  75. func main() {
  76. maze := readMaze("maze/maze.in")
  77. /*for _, row := range maze {
  78. for _, val := range row {
  79. fmt.Printf("%d ", val)
  80. }
  81. fmt.Println()
  82. }*/
  83. steps:=walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
  84. for _,row:=range steps {
  85. for _,val:=range row{
  86. fmt.Printf("%3d",val)
  87. }
  88. fmt.Println()
  89. }
  90. }

结果:

总结

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

 

文章来源: blog.csdn.net,作者:lxw1844912514,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/lxw1844912514/article/details/108586572

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。