关闭

编程珠玑 习题 十二章

186人阅读 评论(0) 收藏 举报

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

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] ;反复进行直到链表遍历完。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21131次
    • 积分:448
    • 等级:
    • 排名:千里之外
    • 原创:23篇
    • 转载:2篇
    • 译文:0篇
    • 评论:7条
    最新评论