1. 位图表示,习题2

这章除了讲述要准确描述问题,还介绍了用位图来尽可能多的存储数据,习题2的答案给出了具体的代码,这里个人感觉BITSPERWORD并不是每个数的位数,而是最大值+1,SHIFT才是,也就是每个数组里的数能表示32个数,MASK则是一个5位全是1的掩码,此外:

  1. i >> SHIFT 相当于 i/32 的结果,也就是寻找i应该在数组的第几位;
  2. i & MASK 相当于 i%32 的结果,也就是寻找i在第一步找到的那个数里,在bit级别上的offset;
  3. 1 << (i & MASK),结果是一个第K位为1其他位为0的数,K = i & MASK,也就是让第二步对应的那个bit取1;
  4. set用或操作,也就是说不仅让i对应的bit取1,如果有已经存储的,则保留;
  5. clr用与操作,并且进行了取反,相当于仅仅让i对应的bit取0,其它不变;
  6. test用与,因为(1<<(i & MASK))只有i对应的bit是1,因此如果数组里这个bit不是1,那么test就会返回0;

2. 随机数,习题4

这里讲了一个如何产生K个不重复随机数的过程,以前遇到过类似场景,没有仔细思考过,这里是直接从前到后遍历,不停交换当前位置与后面随机位置的元素,从而起到随机的效果,思路值得借鉴。

3. 习题8

书中没有给出答案,个人觉得排序的话仍然借助多趟排序即可,只是不再是7位而是10位,因为设定上所有区号都可能是免费的;查找的话二分应该就可以了,每个文件按顺序存储一部分。

4. 习题9

题目感觉有点绕,因为感觉以汇编层面的技术,全部初始化为0并不是复杂度特别高的行为,根据题目,应该有如下要求:

  1. 不能直接一个循环全部设成0,因为要求是第一次访问时设为0,如果提前设置了,下次访问就不是第一次了;
  2. get和set都是访问,在没有设置过数组时,get应该得到0;
  3. get和set的时间复杂度应该是O(1),空间复杂度应该是O(n);

假设data是目标数组,那么我们应该需要如下信息:

  1. 有一个数组记录了data[i]是否被初始化过,但因为这个数组不能初始化(不然就可以用布尔数组了),因此用双射的办法,也就是答案里,from[i] = top,to[top] = from,这样还有了另外一个约束就是from[i] < top,因为这步操作后top要自增;总共用了两个数组和一个常数,空间复杂度是O(n)的;
  2. 当使用get和set时,检测是否满足上述条件,不满足说明没有初始化,执行上述条件并data[i] = 0,否则直接执行get和set即可,这样操作就是O(1)的了;

邹开发
1 声望0 粉丝

惟爱与梦想不可辜负。


引用和评论

0 条评论