有时我们需要一些随机数但不重复,通常随机数是伪随机的,它们肯定有重复的机会。假设我们有一个数字范围,我们希望在该范围之间以随机方式排列 n 个元素。

使用 rand.Perm

我们将首先创建一个具有任何适当名称并具有 .go 扩展名的文件。我们将在 Golang 中使用数学随机模块,因此我们需要导入该模块。

开始实现

// Go program generating an array of unique random numbers 
package main
  import (
    "fmt"
    "math/rand"
)
  func main() {
    permutation := rand.Perm(5)
      fmt.Println(permutation)
}

输出:

[0 4 2 3 1]

正如我们所看到的,它提供了一个排列来一次排列五个随机的对象,但它不会在每次运行或迭代后改变顺序。所以我们并没有完全生成一个随机列表,我们每次都需要有不同的排列顺序。所以,为了做到这一点,我们将 random 模块与 time 模块一起使用。我们需要生成一个不同的种子,以便置换函数打乱顺序。默认情况下,种子保持不变,但如果我们将当前时间添加为种子,它会产生不同的种子,进而相应地生成顺序。

为了增加这种随机性,我们需要使用 time 模块,在里面我们需要获取当前时间,可以通过使用 time.Now() 来获取,这给出了 date 中的当前时间-时间格式。这种格式不能用作种子,所以我们使用 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 numbers 并将数字 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)
}

输出:

因此,我们可以看到在排列函数的帮助下,范围之间的元素数量得到了排列。不,我们将研究如何使这些值实际介于最小和最大范围之间。

创建一个从最小值到最大值排列的数组

要获得最小和最大范围之间的元素值,我们只需将最小限制添加到所有元素。它最终会被容纳在给定的范围内。

对于 i := 范围置换 {

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)
    }
    */
}

注释中的代码基本上是遍历生成的数组,即唯一的随机列表,并将元素一个一个打印出来。