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

举报
福大大架构师每日一题 发表于 2020/08/19 09:54:57 2020/08/19
【摘要】 福哥答案2020-04-19:构造一个一一映射x→f(x)。定义域和值域都是0到999999,当x加1时,y的变化必须看起来杂乱无章。然后从0到99万循环x,打印f(x)。直接找杂乱无章的f(x)是可以的,由于我不是专门研究数学的,就不考虑了。分块+每位随机。100万以内的数字总共有6位,个位,十位,百位,千位,万位,十万位。为了方便描述,假设1-100,只有个位和十位。 序号:...

福哥答案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 结果如下:

image.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。