我试图在Go中生成一个随机字符串,这是我迄今为止写的代码:
package main
import (
"bytes"
"fmt"
"math/rand"
"time"
)
func main() {
fmt.Println(randomString(10))
}
func randomString(l int) string {
var result bytes.Buffer
var temp string
for i := 0; i < l; {
if string(randInt(65, 90)) != temp {
temp = string(randInt(65, 90))
result.WriteString(temp)
i++
}
}
return result.String()
}
func randInt(min int, max int) int {
rand.Seed(time.Now().UTC().UnixNano())
return min + rand.Intn(max-min)
}
我的实现非常缓慢。使用时间的播种在特定的时间内带来相同的随机数,因此循环一次又一次地迭代。我如何改进我的代码?
每次你设置相同的种子,你会得到相同的序列。当然,如果你在一个快速循环中设置时间的种子,你可能会用同一个种子多次调用它。
在你的例子中,当你调用randInt函数直到你有一个不同的值,你在等待时间(由Nano返回)改变。
对于所有伪随机库,您只需设置一次种子,例如在初始化程序时,除非您特别需要重新生成给定的序列(这通常只用于调试和单元测试)。
在此之后,您只需调用Intn来获得下一个随机整数。
将rand.Seed(time.Now(). utc (). unixnano())行从randInt函数移动到main函数的开头,一切都会更快。失去.UTC()调用,因为:
UnixNano返回t作为Unix时间,即自UTC 1970年1月1日以来经过的纳秒数。
还要注意,我认为你可以简化你的字符串构建:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(randomString(10))
}
func randomString(l int) string {
bytes := make([]byte, l)
for i := 0; i < l; i++ {
bytes[i] = byte(randInt(65, 90))
}
return string(bytes)
}
func randInt(min int, max int) int {
return min + rand.Intn(max-min)
}
每次在for循环中调用randint()方法时,都会设置一个不同的种子,并根据时间生成一个序列。但是由于循环在您的计算机中运行得很快,在很短的时间内,种子几乎是相同的,并且由于时间的原因,生成的序列与过去的序列非常相似。因此,将种子设置在randint()方法之外就足够了。
package main
import (
"bytes"
"fmt"
"math/rand"
"time"
)
var r = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
func main() {
fmt.Println(randomString(10))
}
func randomString(l int) string {
var result bytes.Buffer
var temp string
for i := 0; i < l; {
if string(randInt(65, 90)) != temp {
temp = string(randInt(65, 90))
result.WriteString(temp)
i++
}
}
return result.String()
}
func randInt(min int, max int) int {
return min + r.Intn(max-min)
}
如果你的目标只是生成一个随机数刺,那么我认为没有必要用多次函数调用或每次重置种子来复杂化它。
最重要的一步是在实际运行rand.Init(x)之前只调用一次种子函数。Seed使用提供的种子值将默认Source初始化为确定状态。因此,建议在实际函数调用伪随机数生成器之前调用它一次。
下面是创建随机数字符串的示例代码
package main
import (
"fmt"
"math/rand"
"time"
)
func main(){
rand.Seed(time.Now().UnixNano())
var s string
for i:=0;i<10;i++{
s+=fmt.Sprintf("%d ",rand.Intn(7))
}
fmt.Printf(s)
}
我使用Sprintf的原因是它允许简单的字符串格式化。
此外,In rand.Intn(7) Intn作为int返回[0,7)中的非负伪随机数。