产生不重复随机数-with python

这个问题算是一个简单的算法题吧,简单的不能再简单了。今天强迫症似的想要把它实现主要是想担心以后面试的时候面试官问。万一由像上次一样半天憋不出来,憋出来还是个错的或者是压根没办法认真跑的,就非常的迷了~

这里给出算法的两种参数设置的实现,第一种是在[0, m)中,第二种是可以设定两个参数,范围任选。

从[0, m)中产生n个随机数

要求:m, n 为正整数,m >= n

算法实现如下,具体的思想可以参考代码注释,不复杂,想弄明白还请认真看。


def nfromm(m, n, unique=True):
    """
    从[0, m)中产生n个随机数
    :param m:
    :param n:
    :param unique:
    :return:
    """
    if unique:
        box = [i for i in range(m)]
        out = []
        for i in range(n):
            index = random.randint(0, m - i - 1)

            # 将选中的元素插入的输出结果列表中
            out.append(box[index])

            # 元素交换,将选中的元素换到最后,然后在前面的元素中继续进行随机选择。
            box[index], box[m - i - 1] = box[m - i - 1], box[index]
        return out
    else:
        # 允许重复
        out = []
        for _ in range(n):
            out.append(random.randint(0, m - 1))
        return out

从[a, b)中产生n个随机数

要求:a, b, n 是正整数, b > a,b - a > n

代码实现如下,借用了上面的实现函数:

def nfromrange(region, n, unique=True):
    """
    从(a, b)
    :param region: (a, b) => [a, b)
    :param n: 个数
    :param unique: 是否允许重复
    :return:
    """
    assert isinstance(region, tuple)
    down, up = region
    if unique:
        box = [i for i in range(down, up)]
        indexs = [i + down for i in nfromm(len(box), n, unique)]
        return indexs
    else:
        out = []
        for _ in range(n):
            out.append(random.randint(down, up - 1))
        return out

ps python写算法真的很爽啊~

最后的最后,如果大家真的把上面的代码看完了,非常感谢。但是如果你不在乎代码本身而更在意工程实现和使用的话,这里有一个更适合您的版本哦,就在random(build in)里面

import random
m = 10
n = 5
random.sample(range(m), n)
# 或者
a = -5
b = 5
random.sample(range(a, b), n)

python标准库就是这么强啊。
这里顺便放上python标准库对这个算法的实现

def sample(self, population, k):
    if isinstance(population, _Set):
        population = tuple(population)
    if not isinstance(population, _Sequence):
        raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
    randbelow = self._randbelow
    n = len(population)
    if not 0 <= k <= n:
        raise ValueError("Sample larger than population")
    result = [None] * k
    setsize = 21        # size of a small set minus size of an empty list
    if k > 5:
        setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
    if n <= setsize:
        # An n-length list is smaller than a k-length set
        pool = list(population)
        for i in range(k):         # invariant:  non-selected at [0,n-i)
            j = randbelow(n-i)
            result[i] = pool[j]
            pool[j] = pool[n-i-1]   # move non-selected item into vacancy
    else:
        selected = set()
        selected_add = selected.add
        for i in range(k):
            j = randbelow(n)
            while j in selected:
                j = randbelow(n)
            selected_add(j)
            result[i] = population[j]
    return result

思想似乎是一样一样的~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值