2020-04-19:1到100万以内,如何打印99万个不重复的随机数?
福哥答案2020-04-19:
构造一个一一映射x→f(x)。定义域和值域都是0到999999,
当x加1时,y的变化必须看起来杂乱无章。
然后从0到99万循环x,打印f(x)。
直接找杂乱无章的f(x)是可以的,由于我不是专门研究数学的,就不考虑了。
分块+每位随机。100万以内的数字总共有6位,个位,十位,百位,千位,万位,十万位。为了方便描述,假设1-100,只有个位和十位。
序号:0 1 2 3 4 5 6 7 8 9
个位随机:3 8 2 4 0 1 9 7 5 6
十位随机:1 6 8 9 2 5 7 0 3 4
x→y x从0开始自增1,y看起来杂乱无章
00→13
01→18
02→12
03→14
04→10
05→11
这个结果有个问题,个位看起来随机了,但是十位的数字并没有发生变化,很明显不随机。
十位数值 = 十位数值减去个位数值,这看起来就变得随机了。如下:
00→13→83
01→18→38
02→12→92
03→14→74
04→10→10
05→11→01
福哥答案2020-06-04:
04-19答案,生成的随机数,有规律。所以新增了算法来规避这种规律性。方法如下:
两个十进制合并成一个百进制,替换后,一个百进制拆分成两个十进制。
golang代码如下:
package test17_1_100w import ( "fmt" "math/rand" "strconv" "testing" "time" ) const ( DIGIT = 6 ) //十进制随机数列表 var randnumlist1 [][]int //百进制随机数列表 var randnumlist2 [][]int func init() { randnumlist1 = [][]int{ {4, 5, 8, 7, 1, 2, 9, 6, 0, 3}, {2, 4, 9, 3, 1, 0, 7, 6, 8, 5}, {2, 3, 1, 5, 8, 9, 6, 4, 0, 7}, {3, 5, 2, 6, 0, 4, 8, 9, 7, 1}, {1, 0, 9, 6, 8, 4, 3, 7, 5, 2}, {4, 3, 0, 2, 9, 5, 7, 1, 6, 8}} randnumlist2 = [][]int{ {22, 99, 56, 73, 69, 65, 8, 20, 68, 83, 85, 89, 14, 90, 66, 25, 70, 49, 91, 79, 26, 58, 18, 9, 30, 87, 44, 93, 24, 4, 19, 88, 40, 41, 31, 3, 7, 72, 71, 81, 86, 50, 13, 78, 67, 63, 92, 10, 1, 96, 77, 53, 64, 76, 16, 54, 29, 59, 43, 94, 60, 52, 27, 0, 36, 95, 6, 37, 5, 39, 17, 82, 12, 2, 46, 57, 23, 84, 98, 38, 42, 75, 62, 80, 35, 47, 97, 51, 33, 55, 48, 45, 15, 61, 32, 11, 34, 28, 21, 74}, {93, 13, 67, 78, 71, 63, 6, 60, 76, 23, 89, 24, 56, 9, 88, 66, 45, 20, 90, 32, 68, 19, 72, 84, 7, 64, 41, 83, 34, 29, 69, 70, 28, 61, 25, 4, 16, 35, 86, 42, 58, 5, 65, 75, 95, 10, 12, 31, 37, 73, 0, 92, 38, 2, 48, 62, 82, 1, 21, 97, 44, 53, 49, 11, 51, 77, 47, 18, 3, 96, 52, 8, 17, 15, 91, 26, 85, 55, 46, 87, 27, 33, 40, 59, 43, 81, 94, 74, 36, 79, 39, 80, 22, 54, 14, 99, 50, 98, 57, 30}, {50, 43, 88, 24, 69, 51, 23, 65, 18, 47, 25, 90, 95, 10, 4, 85, 45, 64, 94, 32, 87, 19, 33, 49, 17, 42, 86, 12, 67, 27, 80, 3, 37, 34, 31, 46, 66, 96, 82, 8, 98, 61, 63, 6, 48, 77, 2, 56, 40, 81, 74, 30, 38, 89, 53, 22, 93, 20, 39, 72, 54, 14, 15, 83, 44, 0, 92, 62, 97, 29, 7, 11, 1, 76, 68, 41, 75, 84, 52, 73, 91, 16, 5, 36, 58, 57, 13, 78, 59, 9, 28, 21, 35, 55, 71, 99, 60, 70, 26, 79}, {70, 84, 57, 69, 32, 72, 94, 65, 66, 29, 82, 75, 15, 60, 76, 79, 42, 49, 55, 12, 0, 22, 48, 41, 73, 97, 43, 61, 26, 53, 80, 85, 3, 71, 54, 77, 21, 34, 86, 8, 78, 50, 31, 6, 28, 5, 24, 14, 47, 1, 90, 20, 37, 46, 62, 39, 33, 10, 9, 58, 89, 59, 99, 45, 35, 88, 83, 81, 51, 30, 96, 4, 36, 17, 2, 74, 68, 56, 92, 40, 11, 67, 23, 44, 13, 18, 38, 7, 87, 52, 63, 98, 27, 91, 64, 19, 25, 93, 95, 16}, {30, 4, 82, 77, 53, 14, 29, 48, 47, 95, 73, 19, 64, 79, 33, 46, 66, 56, 35, 51, 72, 87, 89, 34, 86, 58, 11, 28, 24, 67, 97, 69, 9, 37, 92, 94, 21, 40, 6, 59, 71, 68, 90, 45, 96, 0, 41, 20, 18, 42, 85, 74, 65, 13, 83, 84, 31, 8, 75, 55, 50, 5, 25, 2, 32, 39, 12, 80, 62, 3, 81, 93, 26, 23, 16, 38, 52, 60, 1, 7, 98, 76, 61, 44, 27, 54, 17, 10, 70, 78, 49, 15, 36, 99, 63, 57, 22, 43, 88, 91}, {90, 43, 15, 85, 58, 78, 62, 89, 57, 30, 31, 9, 33, 63, 61, 12, 86, 47, 55, 91, 1, 97, 80, 87, 60, 56, 71, 81, 32, 77, 10, 99, 16, 52, 72, 19, 37, 2, 18, 5, 13, 75, 35, 42, 49, 4, 94, 22, 29, 23, 39, 41, 51, 68, 67, 88, 24, 66, 82, 38, 45, 28, 74, 96, 14, 46, 27, 73, 69, 79, 53, 17, 65, 95, 40, 7, 6, 93, 21, 44, 92, 83, 36, 25, 54, 48, 70, 76, 98, 50, 0, 84, 34, 20, 26, 3, 59, 11, 8, 64}, } } //打印[0,9]之间的随机数 //go test -v -test.run TestPrint10Rand func TestPrint10Rand(t *testing.T) { rand.Seed(time.Now().UnixNano()) nums := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} numsret := make([]int, 0) for i := 0; i < 10; i++ { tempindex := rand.Intn(10 - i) numsret = append(numsret, nums[tempindex]) nums = append(nums[0:tempindex], nums[tempindex+1:]...) } fmt.Println(numsret) fmt.Println("") } //打印[0,99]之间的随机数 //go test -v -test.run TestPrint100Rand func TestPrint100Rand(t *testing.T) { rand.Seed(time.Now().UnixNano()) nums := make([]int, 100) for i := 0; i < 100; i++ { nums[i] = i } numsret := make([]int, 0) for i := 0; i < 100; i++ { tempindex := rand.Intn(100 - i) numsret = append(numsret, nums[tempindex]) nums = append(nums[0:tempindex], nums[tempindex+1:]...) fmt.Print(numsret[i], ",") } //fmt.Println(numsret) fmt.Println("") } //go test -v -test.run TestGetRand func TestGetRand(t *testing.T) { //fmt.Println(GetRand(2)) dic := make(map[string]struct{}) temp := "" for i := 0; i < 10000; i++ { temp = GetRand(i) dic[temp] = struct{}{} fmt.Println(temp) } fmt.Println("len(dic) = ", len(dic)) } //生成随机数 func GetRand(num int) string { //数字拆分成数组,方便计算 numarr := make([]int, DIGIT) for i := 0; i < DIGIT; i++ { numarr[i] = num % 10 num /= 10 } //按位替换,每位随机 for i := 0; i < DIGIT; i++ { numarr[i] = randnumlist1[i][numarr[i]] } //十位数值 = 十位数值减去个位数值 if true { for i := 1; i < DIGIT; i++ { numarr[i] -= numarr[i-1] if numarr[i] < 0 { numarr[i] += 10 } } numarr[0] -= numarr[DIGIT-1] if numarr[0] < 0 { numarr[0] += 10 } } //两个十进制合并成一个百进制,替换后,一个百进制拆分成两个十进制 temp := 0 for i := 1; i < DIGIT; i++ { temp = numarr[i]*10 + numarr[i-1] temp = randnumlist2[i][temp] numarr[i-1] = temp % 10 numarr[i] = temp / 10 } temp = numarr[0]*10 + numarr[DIGIT-1] temp = randnumlist2[0][temp] numarr[DIGIT-1] = temp % 10 numarr[0] = temp / 10 //生成字符串 ret := "" for i := DIGIT - 1; i >= 0; i-- { ret += strconv.Itoa(numarr[i]) } return ret }
敲命令 go test -v -test.run TestGetRand 结果如下:
福大大架构师每日一题 文章被收录于专栏
最新面试题,针对高级开发人员和架构师。内容是后端、大数据和人工智能。