用go语言完成深搜Bfs的“走迷宫”算法。从迷宫的[1][1]点,走到迷宫右下角(迷宫大小可变,因此数组要用切片数组).
然后自己拟造简单数据,完成test和benchmark(测时间)
在bfs_test.go中
package iteration import "testing" func TestBfs(t *testing.T){ var m [][]int; ans:=Bfs(m); excepted:=-1; if (ans!=excepted){ t.Errorf("we want %d,but %d",excepted,ans); } }在bfs.go中
package iteration func Bfs(m [][]int) int{ return 5; }此时执行
go test XXX结果:
--- FAIL: TestBfs (0.00s) bfs_test.go:12: we want -1,but 5 FAIL FAIL bo 0.500s FAIL C:\Users\ASUS>编译正确,符合预期
框架已经打出来了,接下来是Bfs的代码,还有在test函数中地图的构建
go语言里数组大小也在函数传参的考虑范围里。 例如:
func Arratfunction(a [][]int){ } a:=[3][3]int; ArrayFunction(a);就无法通过编译。
所以这里必须使用切片数组(相当与c语言里数组指针,动态分配数组) 切片数组的长度可动态分配,无论长度如何切片都可以传参。
这样迷宫大小就不是考虑问题了(可以用len()函数获得尺寸)
二维切片数组的分配例子:
var m [][]int=make([][]int,101); for i:=0;i<101;i++ { m[i]=make([]int,51); }一个101*51的二维切片数组。
我不喜欢0,所以都分配多一点,呜呜呜呜
深搜在此不做解释
在bfs.go中:
package bfs import "fmt" type point struct { x int; y int; } func Bfs(m [][]int) int { var q [10050]point; h:=0;t:=1; q[1].x=1;q[1].y=1; var height int =len(m); var width int=len(m[0]); var vis [][]bool; vis=make([][]bool,height); for i:=0;i<height;i++ { vis[i]=make([]bool,width); } var step [][]int; step=make([][]int,height); for i:=0;i<height;i++{ step[i]=make([]int,width); } for i:=0;i<height;i++{ for j:=0;j<width;j++{ vis[i][j]=false; step[i][j]=-1; } } vis[1][1]=true; step[1][1]=0; height=height-1; width=width-1; var dir [5][3]int; dir[1][1]=1;dir[1][2]=0; dir[2][1]=0;dir[2][2]=1; dir[3][1]=-1;dir[3][2]=0; dir[4][1]=0;dir[4][1]=-1; for ;h!=t; { h++; now:=q[h]; x:=now.x; y:=now.y; for i:=1;i<4;i++ { nx:=x+dir[i][1]; ny:=y+dir[i][2]; if nx<=0 || nx>height || ny<=0||ny>width { continue; } if vis[nx][ny]==false && m[nx][ny]==1 { vis[nx][ny]=true; step[nx][ny]=step[x][y]+1; t++; q[t].x=nx; q[t].y=ny; } } } fmt.Printf(""); /* ans debug for i:=1;i<=height;i++{ for j:=1;j<=width;j++{ fmt.Printf("%d ",step[i][j]); } fmt.Printf("\n"); } */ return step[height][width]; }主要就是拟造数据
package bfs import "testing" func TestBfs(t *testing.T) { var m [][]int=make([][]int,101); for i:=0;i<101;i++ { m[i]=make([]int,51); } //先建立无障碍迷宫 for i:=0;i<101;i++{ for j:=0;j<51;j++{ m[i][j]=1; } } // 在迷宫中加入两堵墙,让计算机绕路 for i:=1;i<=99;i++ { m[i][3]=0; } for i:=2;i<=100;i++{ m[i][5]=0; } excepted:=346;//脑算答案 ans:=Bfs(m); if ans!=excepted { t.Errorf("we want %d , but we get %d",excepted,ans); } }这里画了一个大致是这样的迷宫:
绕个弯子就走到了答案是346(具体数据见代码)
go test测试结果:
ok hw2 0.451s说明答案正确
如果更改excepted为-1呢?(故意出错) 结果:
bfs_test.go:30: we want -1 , but we get 346说明测试是可靠的。
在bfs_test.go中加入函数 BenchmarkBfs(b *testing.B)
func BenchmarkBfs( b* testing.B){ var m [][]int=make([][]int,101); for i:=0;i<101;i++ { m[i]=make([]int,51); } //先建立无障碍迷宫 for i:=0;i<101;i++{ for j:=0;j<51;j++{ m[i][j]=1; } } // 在迷宫中加入两堵墙,让计算机绕路 for i:=1;i<=99;i++ { m[i][3]=0; } for i:=2;i<=100;i++{ m[i][5]=0; } for i:=0;i<b.N;i++{ Bfs(m); } }然后运行
go test XXX -bench="."运行结果:
goos: windows goarch: amd64 pkg: hw2 BenchmarkBfs-16 20274 60140 ns/op PASS ok hw2 2.294s表明运行了20274次,每次60140纳秒