介绍enumerateMask的实现。(仅供理解,非严谨证明)
 
 
1. 基本定义
 
enumerateMask的意思是枚举掩码。其功能是把mask中为1的位的所有组合枚举出来。
 
enumerateMask方法的功能比较简单独立,可以直接执行进行验证:
 
执行结果如下:
 
2. helper(id, tail)
 
helper方法有两个参数:
a. id:指当前枚举的mask;
b. tail:包含已经枚举的mask;
 
第一个被枚举的mask为0,即不包含任何比特位。
所以helper的初始调用为:helper(0, Nil)
 
3. id == mask
 
若id == mask,则id中已经包含了mask中所有的为1的比特,所以可以结束枚举过程了。
可以看出,枚举的过程是从0到mask,逐渐增加id中1的位数,id成递增变化,搜集所有组合。
 
4. id != mask
 
若id != mask,则把id加入到tail中,计算下一个id,并继续进行枚举。
 
 
5. mask中为0的位
 
 
next_id = ((~mask | id) + 1) & mask
 
因为最后都是要和mask相与,所以mask中为0的位,在next_id中也同样为0。
 
所以:
a. mask中为0的位,在id中对应的位始终为0。
b. id中为1的位,在mask中对应的位一定为1。
 
另外:
c. mask中为0的位,直接向高位透传被加的1。
 
6. mask为全1
 
 
即next_id = id + 1。
 
7. mask中的0:相当于不存在
 
next_id = ((~mask | id) + 1) & mask
 
a. ~mask:mask取反会将其中为1的位也取反,但最后&mask之后会被清除,不在最终结果中出现;
b. |id:id中为1的位在mask中也都为1,所以“|id”的逻辑运算不涉及mask中为0的位;
c. +1:mask中为0的位,向高一位透传加1的动作,自己本身的值在加1之后虽然有变化,但不在最终结果中体现;加1的动作必定在mask中某一个为1的位结束;
 
所以,可以忽略mask中0的存在,直接把mask中为1的位提取出来进行运算(如同第6节所述),然后再把0填到结果的相应位中即可。
 
 
8. 附录
 
def enumerateMask(mask: BigInt): Seq[BigInt] = {
def helper(id: BigInt, tail: Seq[BigInt]): Seq[BigInt] =
if (id == mask) (id +: tail).reverse else helper(((~mask | id) + 1) & mask, id +: tail)
helper(0, Nil)
}
 
 

最新文章

  1. 代码的坏味道(11)——霰弹式修改(Shotgun Surgery)
  2. 腾讯AlloyTeam移动Web裁剪组件AlloyCrop正式开源
  3. css实现图片闪光效果
  4. c#输出、输入练习
  5. [原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程
  6. XUtils框架的学习(一)
  7. git版本号管理工具的上手
  8. HDU 5730 - Shell Necklace
  9. rootvg 镜像
  10. 团队作业4——第一次项目冲刺 FiFtH DaY
  11. linux下编译sphinx拓展
  12. Java项目转换成Web项目
  13. 抓包工具tcpdump用法说明
  14. Ubuntu16.04 创建和使用虚拟环境
  15. BF算法(模式匹配)
  16. 如何计算PCB设计中的阻抗
  17. 使用Numpy实现卷积神经网络(CNN)
  18. MFC剪贴板通信
  19. sql 获取列名
  20. Scala的文件读写操作与正则表达式

热门文章

  1. F - Qualification Rounds CodeForces - 868C 二进制
  2. WPF客户端自动升级
  3. SQL SERVER 函数举例
  4. 基于BasicRF点对点无线开发基础知识
  5. 【mybatis】IF判断的坑
  6. lammps 学习之:系统压力太大,导致原子丢失
  7. 【Scala】scala的继承能干嘛?这段简单的代码或许能帮你梳理
  8. Boosting算法总结(ada boosting、GBDT、XGBoost)
  9. html之常用input type
  10. 配置centos7 java环境