如何在 Golang 中生成唯一随机数数组?
有时我们需要一些随机数但不重复,一般随机数是伪随机的,其中肯定有重复的机会。假设我们有一个数字范围,并且我们希望在该范围之间以打乱的方式有 n 个元素。
使用 rand.Perm
简单地说,我们将首先创建一个具有任何适当名称并具有 .go 扩展名的文件。我们将在 Golang 中使用数学随机模块,因此我们需要导入该模块。
Go
// Go program generating an array of unique random numbers
package main
import (
"fmt"
"math/rand"
)
func main() {
permutation := rand.Perm(5)
fmt.Println(permutation)
}
Go
// Go program generating an array of unique random numbers
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
permutation := rand.Perm(5)
fmt.Println(permutation)
}
Go
// Go program to define a range for numbers in the list
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
min := 3
max := 7
permutation := rand.Perm(max - min + 1)
fmt.Println(permutation)
}
Go
// Go program to take user input for min-max and see the
// permutation function display the numbers
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
var min int
var max int
fmt.Print("Enter the min number: ")
fmt.Scan(&min)
fmt.Print("Enter the max number: ")
fmt.Scan(&max)
permutation := rand.Perm(max - min + 1)
fmt.Println(permutation)
}
Go
// Go program for creating an array with permutation from min to max
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
var min int
var max int
fmt.Print("Enter the min number: ")
fmt.Scan(&min)
fmt.Print("Enter the max number: ")
fmt.Scan(&max)
random_list := rand.Perm(max - min + 1)
for i := range random_list {
random_list[i] += min
}
fmt.Println(random_list)
/*
for _, num := range random_list {
fmt.Println(num)
}
*/
}
输出:
[0 4 2 3 1]
正如我们所看到的,它给出了一次排列五个随机对象的排列,但它不会在每次运行或迭代后改变顺序。所以我们并没有完全生成一个随机列表,我们每次都需要有不同的排列顺序。所以,为了做到这一点,我们将 random 模块与 time 模块一起使用。我们需要生成一个不同的种子,以便置换函数打乱顺序。默认情况下,种子保持不变,但如果我们将当前时间添加为种子,它会产生不同的种子,并相应地生成顺序。
要添加这种级别的随机性,我们需要使用 time 模块,在其中我们需要获取当前时间,可以通过使用 time.Now() 获取,这以日期时间格式给出当前时间。这种格式不能用作种子,所以我们使用 Unix函数转换为秒。 Unix函数给出自 1970 年 1 月 1 日以来的秒数。您甚至可以使用 UnixNano、UnixMicro 或 UnixMill。这些只是以纳秒、微秒和毫秒为单位返回 Unix 秒。
rand.Seed(time.Now().Unix())
因此,如果我们将以下命令添加到脚本中,置换函数将随机生成订单。
去
// Go program generating an array of unique random numbers
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
permutation := rand.Perm(5)
fmt.Println(permutation)
}
输出:
[4 0 1 2 3]
定义列表中数字的范围
要定义范围,我们可以输入来自用户的范围,或者只是将它们设置为固定值。然而,置换函数不允许输入最小和最大范围,它只是返回n 个数字,按从 0 到 n-1 的顺序提供 n 作为函数的参数。
去
// Go program to define a range for numbers in the list
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
min := 3
max := 7
permutation := rand.Perm(max - min + 1)
fmt.Println(permutation)
}
输出:
[3 4 0 1 2]
我们将使用 min 和 max 变量来设置生成数字的最小值和最大值。因此,要生成提供的最小和最大范围之间的数字,我们可以将max-min+1传递给函数,因为它会生成所需的数字。我们正在添加一个,因为范围包括在内。例如,这里的最小值是 3,最大值是 7,我们显然有 5 个值可供选择,即 3、4、5、6、7,因此公式完全符合 max-min+1。因此,我们有 5 个数字并将数字 5 作为 Permutation函数的参数,它将以随机顺序呈现数字 0 到 5-1,即 [0 1 2 3 4] 以随机顺序。
为了测试这一点,我们可以为 min-max 添加用户输入,并查看排列函数显示的数字。
去
// Go program to take user input for min-max and see the
// permutation function display the numbers
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
var min int
var max int
fmt.Print("Enter the min number: ")
fmt.Scan(&min)
fmt.Print("Enter the max number: ")
fmt.Scan(&max)
permutation := rand.Perm(max - min + 1)
fmt.Println(permutation)
}
输出:
因此,我们可以看到范围之间的元素数量是在排列函数的帮助下排列的。不,我们将研究如何使这些值实际介于最小和最大范围之间。
创建一个从最小值到最大值排列的数组
要获得最小和最大范围之间的元素值,我们只需将最小限制添加到所有元素。它最终将被容纳在给定的范围内。
for i := range permutation {
random_list[i] += min
}
因此,这基本上将每个元素移动了最小值,因此数字自动进入(最小值,最大值)之间的范围内。我们在脚本中添加之后,最终变成如下:
去
// Go program for creating an array with permutation from min to max
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
var min int
var max int
fmt.Print("Enter the min number: ")
fmt.Scan(&min)
fmt.Print("Enter the max number: ")
fmt.Scan(&max)
random_list := rand.Perm(max - min + 1)
for i := range random_list {
random_list[i] += min
}
fmt.Println(random_list)
/*
for _, num := range random_list {
fmt.Println(num)
}
*/
}
注释中的代码基本上是迭代生成的数组,即唯一的随机列表,并一一打印元素。