编程珠玑 习题 十二章

注:以下皆为个人理解,非标准答案

12.5.1:

  • bigrandrand函数随机产生15位,那么用两次rand函数再拼接起来就形成了30个随机位
  • randint(l,u)将rand出的数映射到l,u 之间即可,一个实现方法是mod(u-l)+l 

12.5.8:

  • [0..n-1] 中选取 个数并乱序输出先用12.1中的算法产生选出的m个数,然后进行洗牌算法(12.3中所说的‘弄乱)并输出
  • 允许重复,要生成顺序列表每选出一个数后,还是从头遍历数组进行下一次选择;最后排序输出
  • 允许重复,乱序输出:同上,只是省略了排序

12.5.9:

  • 作者坚持要用set的方法并且最多只用m次rand函数:那么必须要避免取到重复数的情况。可以先产生一个数组a[0..n-1]a[i]=i;第j 次循环index = rand() mod (n-j+1),然后取 a[index]  放入set,并用 a[n-j] 替换掉 a[index]。可能看上去比较复杂,思想就是每次从干净的数中取一个放入set,并将该数移除,这样以后就不会取到重复的数;上述方法就是该思想的一个实现

12.5.10:

  • n个对象按序排列,事先不知道n,如何随机输出一个对象:此题的意思我的理解是顺序的读进来若干对象,当读到结束符时就马上随机输出一个对象。既然是随机输出,那么在读完n个对象之前是无法决定输出哪个对象的,否则无法保证每个对象的输出概率相同。这也就是说完全可以记录下n然后 rand() mod n。所以不知道作者这里的出题意图是什么
  • 看到一个类似的题,给你一个长度为 N 的链表。N 很大,但你不知道 N 有多大。你的任务是从这 N 个元素中随机取出 k 个元素。你只能遍历这个链表一次,且必须保证取出的元素是完全随机的同上题,可采用蓄水池算法(Reservoir Sampling),假设选出来的元素存入 R[1..k] 数组中,链表记为 S,首先把遇到的前k个表元素赋值给 R[k],然后遍历 S[k+1]..S[n](下标记为i),j = rand(1,i),如果 j 在1~k范围内则用S[i] 替换 R[j] ;反复进行直到链表遍历完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值