分享
  1. 首页
  2. 文章

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]
}
}

有疑问加站长微信联系(非本文作者)

本文来自:谢权SELF

感谢作者:谢权

查看原文:Go 实现洗牌算法

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
6577 次点击 ∙ 1 赞
2 回复 | 直到 2025年05月15日 08:41:25
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏