分享
Go 实现洗牌算法
谢权 · · 6577 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
shuffle算法,我把它叫做洗牌算法因为他和我们洗扑克牌的方式很像,它的目标正好与各种的sort算法相反,即把一个有序(或者无序)的一系列元素打乱,以满足需求。
如果你是python或者ruby程序员可能你觉得很简单,因为他们在语言层面上实现了很多很方便的函数,然而Go语言要想打乱数组或者切片中数据的顺序,需要自己实现的。
Ruby中有一个叫shuffle的方法:
Ruby
1
2
array=[1,2,3,4,5]
array.shuffle# shuffles the array!
Python也同样非常的简单:
Python
1
2
3
importrandom
array=[1,2,3,4,5]
random.shuffle(array)# shuffles the array!
简单粗暴 – 创建新的数组或者切片
Go
1
2
3
4
5
6
7
8
9
10
11
funcShuffle(vals[]int)[]int{
r:=rand.New(rand.NewSource(time.Now().Unix()))
ret:=make([]int,len(vals))
n:=len(vals)
fori:=0;i<n;i++{
randIndex:=r.Intn(len(vals))
ret[i]=vals[randIndex]
vals=append(vals[:randIndex],vals[randIndex+1:]...)
}
returnret
}
其实我们可以用rand.Perm() 更为高效的实现
Go
1
2
3
4
5
6
7
8
9
funcShuffle(vals[]int)[]int{
r:=rand.New(rand.NewSource(time.Now().Unix()))
ret:=make([]int,len(vals))
perm:=r.Perm(len(vals))
fori,randIndex:=rangeperm{
ret[i]=vals[randIndex]
}
returnret
}
无需创建新的数组或者切片来实现洗牌算法
Go
1
2
3
4
5
6
7
8
funcmain(){
vals:=[]int{10,12,14,16,18,20}
r:=rand.New(rand.NewSource(time.Now().Unix()))
for_,i:=ranger.Perm(len(vals)){
val:=vals[i]
fmt.Println(val)
}
}
运行后发现你可以看到返回的数据已经被打乱了。
如果一个你使用的是切片且不知道切片的大小和容量,且不修改值传递的值,那么我们可以这么做。
Go
1
2
3
4
5
6
7
8
9
funcShuffle(vals[]int){
r:=rand.New(rand.NewSource(time.Now().Unix()))
forlen(vals)>0{
n:=len(vals)
randIndex:=r.Intn(n)
vals[n-1],vals[randIndex]=vals[randIndex],vals[n-1]
vals=vals[:n-1]
}
}
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信6577 次点击 ∙ 1 赞
下一篇:最佳日志实践(v2.0)
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
shuffle算法,我把它叫做洗牌算法因为他和我们洗扑克牌的方式很像,它的目标正好与各种的sort算法相反,即把一个有序(或者无序)的一系列元素打乱,以满足需求。
如果你是python或者ruby程序员可能你觉得很简单,因为他们在语言层面上实现了很多很方便的函数,然而Go语言要想打乱数组或者切片中数据的顺序,需要自己实现的。
Ruby中有一个叫shuffle的方法:
Ruby
1
2
array=[1,2,3,4,5]
array.shuffle# shuffles the array!
Python也同样非常的简单:
Python
1
2
3
importrandom
array=[1,2,3,4,5]
random.shuffle(array)# shuffles the array!
简单粗暴 – 创建新的数组或者切片
Go
1
2
3
4
5
6
7
8
9
10
11
funcShuffle(vals[]int)[]int{
r:=rand.New(rand.NewSource(time.Now().Unix()))
ret:=make([]int,len(vals))
n:=len(vals)
fori:=0;i<n;i++{
randIndex:=r.Intn(len(vals))
ret[i]=vals[randIndex]
vals=append(vals[:randIndex],vals[randIndex+1:]...)
}
returnret
}
其实我们可以用rand.Perm() 更为高效的实现
Go
1
2
3
4
5
6
7
8
9
funcShuffle(vals[]int)[]int{
r:=rand.New(rand.NewSource(time.Now().Unix()))
ret:=make([]int,len(vals))
perm:=r.Perm(len(vals))
fori,randIndex:=rangeperm{
ret[i]=vals[randIndex]
}
returnret
}
无需创建新的数组或者切片来实现洗牌算法
Go
1
2
3
4
5
6
7
8
funcmain(){
vals:=[]int{10,12,14,16,18,20}
r:=rand.New(rand.NewSource(time.Now().Unix()))
for_,i:=ranger.Perm(len(vals)){
val:=vals[i]
fmt.Println(val)
}
}
运行后发现你可以看到返回的数据已经被打乱了。
如果一个你使用的是切片且不知道切片的大小和容量,且不修改值传递的值,那么我们可以这么做。
Go
1
2
3
4
5
6
7
8
9
funcShuffle(vals[]int){
r:=rand.New(rand.NewSource(time.Now().Unix()))
forlen(vals)>0{
n:=len(vals)
randIndex:=r.Intn(n)
vals[n-1],vals[randIndex]=vals[randIndex],vals[n-1]
vals=vals[:n-1]
}
}