2020-04-19:1到100万以内,如何打印99万个不重复的随机数?

构造一个一一映射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 结果如下:

评论

你可能感兴趣的:(2020-04-19:1到100万以内,如何打印99万个不重复的随机数?)