本文要解决的问题是:
给定一个数集,随机生成一个排列,数集中的每个数出现且只出现一次(就像玩扑克牌时洗牌一样,尽量将牌洗散)。
比如,给定数集{2,3,4,5,6,7,8,9,10,11,12} 即:2~12之间的11个整数,随机产生一个长度为11的序列数组,要求2~12之间的每个数都要出现且仅出现一次
示例代码如下:main函数中,调用RandomSequence来生成一个2~12之间所有数的序列
package main
import (
"math/rand"
"sync/atomic"
"time"
"fmt"
"sort"
)
func RandomSequence(min,max int) []int{
//计算序列的长度
lenghth := max - min + 1
//初始化一个长度为lenghth的原始切片,初始值从min到max
initArr := make([]int,lenghth)
for i :=0; i < lenghth; i++{
initArr[i] = i + min
}
//初始化一个长度为lenghth的目标切片
rtnArr := make([]int,lenghth)
//初始化随机种子
rand.Seed(time.Now().Unix())
//生成目标序列
for i :=0; i < lenghth; i++{
//生成一个随机序号
index := rand.Intn(lenghth - i)
//将原始切片中序号index对应的值赋给目标切片
rtnArr[i] = initArr[index]
//替换掉原始切片中使用过的下标index对应的值
initArr[index] = initArr[lenghth - i - 1]
}
return rtnArr
}
func main() {
v := RandomSequence(2,12)
//生成的随机序列
fmt.Printf("size:%d,nmber[]:%v\n", len(v),v)
sort.Ints(v)
//原序列
fmt.Printf("size:%d,nmber[]:%v\n", len(v),v)
}
执行三次结果如下:
size:11,nmber[]:[5 11 4 7 12 9 8 6 10 3 2]
size:11,nmber[]:[2 3 4 5 6 7 8 9 10 11 12]
size:11,nmber[]:[8 11 3 9 12 6 2 7 4 5 10]
size:11,nmber[]:[2 3 4 5 6 7 8 9 10 11 12]
size:11,nmber[]:[6 8 12 5 9 3 11 10 4 7 2]
size:11,nmber[]:[2 3 4 5 6 7 8 9 10 11 12]
从结果看,达到了所要求的“洗牌”效果。