这个问题算是一个简单的算法题吧,简单的不能再简单了。今天强迫症似的想要把它实现主要是想担心以后面试的时候面试官问。万一由像上次一样半天憋不出来,憋出来还是个错的或者是压根没办法认真跑的,就非常的迷了~
这里给出算法的两种参数设置的实现,第一种是在[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
思想似乎是一样一样的~