开发者学堂课程【Go 语言核心编程 - 数据结构和算法: 数据结构和算法—迷宫回溯问题(2)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9864
数据结构和算法—迷宫回溯问题(2)
内容介绍:
一、地图
二、出路
三、死路
一、地图
在有地图的基础上编写函数,完成小老鼠找路。
此代码首先要让小老鼠找迷宫,提供完整地图,同一个地图,写一个函数--func setway,设置一个点,标线,首先把地图拿到,地图应该是引用性的,不可以每次给新的再复制一份。
应该明确两个坐标,还有需要知道你是从那个地方去找,知道两个坐标--i int,j int,代表两个地图,始终要保证是同一个地图,在同一个地图上找,因此使用引用,i 与 j 表示当前是对哪两个格子进行表示。
2代表通路,在找的过程中,如果发现标的点等于2,就是通路,已经分析出找到的关系。
二、出路
什么情况下找到出路,如果 map 就是(6,5)这个点等于2,就是第七行是6,第六列(6,5)等于2就可找到,返回一个布尔值就是找到成功。
如果 map(6,5)等于2,根据规则,2表示通路,即可找到,return ,返回一个值,就是成功找到。如果说这个 map(6,5)不等于2,说明要继续找。
找的过程中要分析出来是不是一堵墙,目标是探测这个点,如果是一堵墙,就不可以探测,找的时候要看能不能探测,如果i或j等于0就能探测,如果点可以探测,而且没有探测过,就探测;
如果不等于0,上来之后直接探测,如果是一堵墙就不能继续探测,说明这个点不能探测,因为等于1是墙,直接 return false,2表示可以通,假设这点是通路,必须要探测才知道,假设可以通,就好像只有假设通过才能知道可能不通过。
根据规则先上,进行探测,一个点有5个,可以向上走、向左走、向下走,涉及一个策略。
一个点有好几种选项,上下左右进行一个选择,假设 setway 把 mymap 传,所以向上走是i - 1,不变,假设路通,即是成功的;如果返回一个真,不知道是那一层返回的,最终 set way ,要理解到他不停的往后探。
如果往上走没有通,就尝试着往下走,else if向下走,加1,即 return true,按照逻辑走的。
如果向下走不通,就向左探测,改变的不是i,j向左是 - 1,此时是返回 true,这个时候只有一个方向成功,只有不成功才会向下走,不成功才会向左走,向左走也不通的,就向右走,向右走不成功,就是上下左右都不通。
三、死路
死路就是在一个点被围死,应该马上置为3,即假设是错的,应该立马置为3,代码完毕。
先来看看效果是否对,如果6和5还不等于2就不能探测,初始情况下等于1,等于0的情况下假设是否能通,在这个点继续往那个逻辑走,不是说在同一个点进行上下左右,假设都走不通就是死路。
使用测试,只需要 setway 把地图传输,传一个地图,从1 1这个点开始探测,为出发点,探完了之后看是不是可以通,探测完毕,看地图能否通。
走代码有问题,全部置成2,走不通,就不停的走,下右上左,尝试换另外一个策略,改成下右上左。
先不要小老鼠探测,直接粘贴过来,地图也粘贴,开始探测。有一个小的指针,小老鼠先向下走,到了一个点,继续采用下右上左的策略,堵住了没有关系,分析起来比较容易,3 1和3 2 加进去,mymap3 1和3 2为一堵墙,两个1代表一个墙。
接着分析,小老鼠先置为2,往下走走不通,不能马上置为3,他还要回到这点,向右走走不通,仍然采用下右上左的策略,于是回溯到这一点,又向下走,可以走通,然后接着向下走,回到一堵墙,做代码,还有问题,就是代码还有问题。map 等于2再调整一下,对策略作相应的改变,向下走,i不动,j+1,下右然后上,j - 1,左边 i 是不用变化的,j减掉1,再继续跑,就会跟策略一样。
假设一个堵死的地图,设置一个挡板,小老鼠就完全不能走,这个地图就需要在1 2 和2 2再加两个点,先来看地图对不对,先把地图输出了,代码执行,看是否出现死循环,分析出是死路,如果不是代码,不等于就不停反推,置成3推,这个就是代码分析。
对地图的点进行测试,开始写代码,刚才规则:1.如果元素的值为1,就是墙2.如果元素的值为0,是没有走过的点3.如果元素的值为2,是一个通路,4.如果元素的值为3,是走过的路,但是走不通。进行递归时,首先要判断出来,什么时候算找到,2代表通,发现右下的点是2,所以走的通,分析出找到的关系,如果mymap[6][5] 这个点等于2,就是通的,如果 mymap 等于2,就可以找到。可以打出一句话,返回一句真,就成功找到;
如果 mymap 不等于2,说明要继续找,问题又来了,找的时候,要分析出它是不是一堵墙,如果本身这个点就是一堵墙,就不需要再继续,如果这个点是可以探测的,而且还没有探测过,就探测;
如果不等于0,比如,如果小球探测直接探测到了,但是不能碰到,说明这个点不能探测,因为是一堵墙,为1,既然是墙的话,就不能走,我先设置为2,先认为是通路,实际上是不是通路,是不知道的,假设是可以通的,假设是通,才可以证明不通,里面有很多概念和逻辑。
四、代码
package main
import(
“fmt”
)
//编写一个函数,完成老鼠找路
//mymap *[8][7]int:地图,保证是同一个地图,使用引用
//i,j表示对地图的哪个点进行测试
func Setway(myMap [8][7]int,i int,j int) bool {
//分析出什么情况下,就找到出路
myMap[6][5] == 2
if myMap[6][5] == 2 {
return true
} else {
//说明要继续找
If myMap[i][j] ==0
//如果这个点是可以探测
//假设这个点是可以通,但是需要探测 上下左右
Mymap[i][j] = 2
If Setway(myMap,i – 1,j) { //
上
return true
}
else
if
Setway(myMap,
i
+ 1,j)
{
//
下
return t
rue
}
else if SetWay(myMap
,
i
,
j - 1)
{
//左
return true
}
else SetWay(myMap
,
i
,
j + 1
)
{ //右
return true
}
else
{
//
死路
myMap[i
]
[j] = 3
return false
}
} else {
// 说明这个点不能探测,为1,是强
return false
//换一个策略 下右上左
Mymap[i][j] = 2
If Setway(myMap,i + 1,j) { //
下
return true
}
else
if
Setway(myMap,
i
,j
+
1
)
{
//
右
return t
rue
}
else if SetWay(myMap
,i
-
1,
j)
{
//
上
return true
}
else SetWay(myMap
,
i
,
j
-
1
)
{ //
左
return true
}
else
{
//
死路
myMap[i
]
[j] = 3
return false
}
} else { // 说明这个点不能探测,为1,是强
return false
Package main
Import (
“fmt”
)
Func main() {
// 先创建一个二维数组,模拟迷宫
// 规则
//1、如果元素的值为1,就是墙
//2、如果元素的值为0,就是没有走过的点
//3、如果元素的值为2,是一个通路
//4、如果元素的值为3,是走过的点,但是走不通
var myMap [8][7]int
//先把地图的最上和最下设置为1
for i: = 0;
i
< 7; i++
{
myMap[
0
][
i
] = 1
myMap[7][i] = 1
}
//先把地图的最左和最右设置为1
for i: = 0; 1< 8; i+ +
{
myMap[i][
0
] = 1
myMap[i][6] = 1
//输出地图
for i: = 0;
i
< 8; i++
{
for j: = 0; j < 7; j++ {
fmt.P
rint(myMap[i][j]),
“”
)
}
∥使用测试
SetWay(&myMap, 1,1)
fmt.PrintIn(("探测完毕…")
∥输出地图
f
or i:=0;i<8;i++ {
for j:=0;j<7;j++ {
}
fmt.
p
rint(myMap[
i
]
[
j],””>
}
fmt Println()
}