Golang 如何获得整数的随机换位

Golang 如何获得整数的随机换位

在Golang中生成随机数是一种常见的需求。但是如何生成随机数,并不止一个方法。有些程序员可能会用时间戳作为seed来生成随机数,有些人可能会用crypto/rand包提供的随机数生成器,这些方法都是可行的,但是如果我们想要生成整数的随机换位,这些方法并不好用。下面我们就来介绍几种实现整数随机换位的方法。

方法一

第一种方法比较简单,就是先将整数转换成字符串,再随机打乱字符串中的字符,最后将字符串转换回整数。这个方式比较容易理解,但是有一个缺点,如果需要处理非常大的整数,这个方法会比较慢。

import (
    "fmt"
    "strconv"
    "math/rand"
    "time"
)

func ShuffleInt(n int) int {
    strn := strconv.Itoa(n)
    r := []rune(strn)
    rand.Seed(time.Now().UnixNano())
    // 这里使用了 Fisher–Yates shuffle 算法
    for i := len(r) - 1; i > 0; i-- {
        j := rand.Intn(i + 1)
        r[i], r[j] = r[j], r[i]
    }
    str := string(r)
    m, _ := strconv.Atoi(str)
    return m
}

func main() {
    n := 123456
    m := ShuffleInt(n)
    fmt.Println(m)  // 可能输出的结果是 341526 或 321546 等等
}

方法二

第二种方法是通过随机交换整数的两个数字来实现的。这个方式比方法一更加高效,因为它不需要将整数转换成字符串再进行操作。而是直接对整数的每一位进行交换。但是需要注意的是,这个方法不能处理有0存在的数字。

import (
    "fmt"
    "math/rand"
    "time"
)

func SwapInt(n int) int {
    a := []int{}
    for n > 0 {
        a = append(a, n%10)
        n /= 10
    }
    rand.Seed(time.Now().UnixNano())
    for i := len(a) - 1; i > 0; i-- {
        j := rand.Intn(i + 1)
        a[i], a[j] = a[j], a[i]
    }
    m := 0
    for i := len(a) - 1; i >= 0; i-- {
        m = m*10 + a[i]
    }
    return m
}

func main() {
    n := 123456
    m := SwapInt(n)
    fmt.Println(m)  // 可能输出的结果是 245316 或者 346521 等等
}

方法三

第三种方法使用的是math/rand包中的perm函数,它可以生成指定长度的随机排列。我们可以先将整数转换成字符串,再将字符串转换成rune类型的数组,然后对这个数组进行随机排列,最后将排列后的数组转换回字符串,再将字符串转换成整数。看起来比方法一和方法二都要简单。

import (
    "fmt"
    "strconv"
    "math/rand"
    "time"
)

func RandPermutation(n int) int {
    strn := strconv.Itoa(n)
    r := []rune(strn)
    rand.Seed(time.Now().UnixNano())
    rand.Shuffle(len(r), func(i, j int) {
        r[i], r[j] = r[j], r[i]
    })
    str := string(r)
    m, _ := strconv.Atoi(str)
    return m
}

func main() {
    n := 123456
    m := RandPermutation(n)
    fmt.Println(m)  // 可能输出的结果是 341526 或 654321 等等
}

结论

在Golang中生成随机数有多种方法,但是如果需要实现整数的随机换位,以上三种方法都是可行的。方法一比较容易理解,可以处理任何大小的数字,但是对于大数字的处理效率较低。方法二效率比方法一高,但是无法处理有0存在的数字。方法三使用的是math/rand包中的perm函数,看起来最简单,但是可能并不高效。因此根据实际情况选择合适的方法是很重要的。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程