1. 6.5如何根据已知随机数生成函数计算新的随机数
已知随机数生成函数rand7()能产生的随机数是整数1–7的均匀分布,如何构造rand10()函数,使其产生的随机数是整数1–10的均匀分布。
思路:
要保证 rand10() 产生的随机数是整数 1--10 的均匀分布,可以构造一个 1--10×n 的均匀分布的随机整数区间(n为任何正整数)。假设 x 是这个 1--10×n 区间上的一个随机数,那么 x%10+1 就是均匀分布在 1--10 区间上的数
所以问题的关键在于,利用 rand7()去构造一个函数,这个函数可以生成 1到10×n 区间上的数。
rand() 函数返回 1 到 7 的随机数,那么 rand7()-1 则得到一个离散整数的集合,该集合为 B={0,1,2,3,4,5,6},该集合中每个整数出现的概率为 1/7;那么 (rand7()-1)*7 得到另外一个离散整数集合 A={0,7,14,21,28,35,42},该集合元素为7的整数倍,集合中每个整数出现的概率也为1/7;显然集合A与集合B中任何两个元素的和的组合可以与1到49之间的一个整数一一对应,即1到49之间的任意一个整数,可以唯一地确定A和B中两个元素的一种组合方,此结论反过来也成立。由于集合A与集合B中元素可以看成是独立事件,根据独立事件的概率公式P(AB)=P(A)×P(B),得到每个组合的概率是 1/7×1/7=1/49。所以 (rand7()-1)×7+rand7() 生成的整数均匀分布在1到49之间,而且每个数的概率为1/49。
所以 (rand7()-1)×7+rand7() 可以构造出均匀分布在 1到49的随机数,为了将49中组合映射到1到10之间的随机数,需要进行截断,即将41到49之间随机数剔除,得到1到40之间的数。这样的话,由1到40区间上的随机数x,可以得到x%10+1就是均匀分布在1到10区间上的整数。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/12 20:42
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
import random
def rand7():
return int(random.uniform(1, 7))
def rand10():
x = 0
while True:
x = (rand7() - 1) * 7 + rand7()
if x < 40:
break
return x % 10 + 1
if __name__ == '__main__':
i = 1
print('result:')
while i <= 10:
print(rand10(), end=' ')
if i % 5 == 0:
print()
i += 1
结果:
2. 6.6如何判断1024!末尾有多少个0
如题,判断1024!末尾有多少个0
思路:
可以用蛮力法,计算出这个数的值,然后再判断,但是算法效率很低,且在数字比较大的时候直接计算阶乘可能会导致数据溢出。
因子法:
5与任何一个偶数相乘都会增加末尾0的个数,由于偶数的个数肯定比5的个数多,所以 1到1024所有数字中有5的因子的数字的个数决定了1024!末尾0的个数。所以,只需要统计因子5的个数即可。此外5与偶数相乘会使末尾增加一个0,25(有两个因子5)与偶数相乘会使末尾增加两个0,125(有3个因子5)与偶数相乘会使末尾增加3个0,625(有4个因子5)与偶数相乘会使末尾增加4个0。
所以,1024!中总共有a1+a2+a3+a4=204+40+8+1=253个因子5,所以末尾总共有253个0。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/12 21:03
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def count0(n):
cnt = 0
while n > 0:
n = n // 5
cnt += n
return cnt
if __name__ == '__main__':
print(f'1024! 末尾有{count0(1024)}个0')
3. 6.7如何按要求比较两个数的大小
如何比较 a、b两个数的大小?不能使用大于、小于及 if 语句。
思路:
根据绝对值的性质可知,若 |a-b|==a-b,那么 max(a,b)=a;若等于b-a,那么max(a,b)=b。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/12 21:11
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def maxs(a, b):
return a if abs(a - b) == a - b else b
if __name__ == '__main__':
print(maxs(5, 6))
4. 6.8如何求有序数列的第 1500 个数的值
一个有序数列,
序列中的每个值都能被2或者3或者5所整数
,1是这个序列的第一个元素,求第1500个数的值。
思路:
可以从1开始往后逐个遍历(每次加1),若遍历到的数能被2或者3或者5整数,那么计数器加1,直至遍历到计数器等于1500时的数即为所求。
数字规律法:
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/12 21:33
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def search(n):
a = [2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 15, 16, 18,
20, 21, 22, 24, 25, 26, 27, 28, 30]
ret = n // 22 * 30 + a[n % 22 - 1]
return ret
if __name__ == '__main__':
print(search(1500))
5. 6.9如何把十进制数(long 型)分别以二进制和十六进制形式输出
思路:
python的左移N位代表乘以2的N次方,右移代表除以2的N次方。所以首先将数值右移 i 位,得到除以2的 i 次方(整除)后的数值b,
如10除以2的0次方,得到b=10;再取b整除2之后的余数0,即二进制的最后一位,以此类推,得到10转换2进制的结果1010
;二进制的位数有64位,以位数为上限,对输入的10进制数字进行循环转换操作,当循环达到64次时终止。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/14 19:56
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def int2Binary(n):
hexNum = 8 * 8 # 二进制的位数(long占8个字符)
bit = []
for i in range(hexNum):
h = n >> i
c, d = divmod(h, 2) # 得到d除以2的商c和余数d
bit.append(str(d)) # 把余数加到列表中
return ''.join(bit[::-1])
def int2Hex(s):
hexs = ''
remainder = 0
while s != 0:
remainder = s % 16
if remainder < 10:
hexs = str(remainder + int('0')) + hexs
else:
hexs = str(remainder - 10 + ord('A')) + hexs
s >>= 4
return chr(int(hexs))
if __name__ == '__main__':
print(f'10的二进制输出为:{int2Binary(10)}')
print(f'10的十六进制输出为:{int2Hex(10)}')
结果:
6. 6.10如何求二进制数中1的个数
给定一个整数,输出这个整数的二进制表示中1的个数。
例如,给定整数7,其二进制表示为111,因此输出结果为3.
方法:
移位法
与操作法
1.移位法
首先,判断这个数的最后一位是否为1,如果为1,那么计数器加1,然后通过右移丢弃最后一位,循环执行该操作直到这个数等于0为止。在判断二进制表示的最后一位是否为1时,可以采用与运算。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/14 20:14
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def count1(n):
count = 0
while n > 0:
if (n & 1) == 1: # 判断最后一位是否为1
count += 1
n >>= 1
return count
if __name__ == '__main__':
print(count1(7))
print(count1(8))
算法性能分析:
时间复杂度为O(n),n为二进制数的位数。
2.与操作法
给定一个数n,每进行一次 n&(n-1)计算,其结果中都会少了一位1,而且是最后一位。
如,n=6,对应的二进制表示位110,n-1=5对应的二进制为101,n&(n-1) 运算后的二进制表示为100,其效果就是去掉了110中最后一位1。可以通过不断地用 n&(n-1)操作去掉 n 中最后一位1的方法求出n的二进制表示中1的个数。
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/2/14 20:23
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
def count1(n):
count = 0
while n > 0:
if n != 0:
n &= (n - 1)
count += 1
return count
if __name__ == '__main__':
print(count1(7))
print(count1(8))
算法性能分析:
时间复杂度为O(m),m为二进制数中1的个数。
end