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 结果如下:
图片说明

福大大架构师每日一题 文章被收录于专栏

最新面试题,针对高级开发人员和架构师。内容是后端、大数据和人工智能。

全部评论

相关推荐

点赞 评论 收藏
分享
和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
3 收藏 评论
分享
牛客网
牛客企业服务