博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Rocket - diplomacy - enumerateMask
阅读量:6126 次
发布时间:2019-06-21

本文共 1205 字,大约阅读时间需要 4 分钟。

 
介绍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)
}
 
 

转载于:https://www.cnblogs.com/wjcdx/p/10669793.html

你可能感兴趣的文章
SQL Server表分区详解
查看>>
使用FMDB最新v2.3版本教程
查看>>
SSIS从理论到实战,再到应用(3)----SSIS包的变量,约束,常用容器
查看>>
STM32启动过程--启动文件--分析
查看>>
垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
查看>>
淘宝的几个架构图
查看>>
Android扩展 - 拍照篇(Camera)
查看>>
JAVA数组的定义及用法
查看>>
充分利用HTML标签元素 – 简单的xtyle前端框架
查看>>
设计模式(十一):FACADE外观模式 -- 结构型模式
查看>>
iOS xcodebuile 自动编译打包ipa
查看>>
程序员眼中的 SQL Server-执行计划教会我如何创建索引?
查看>>
cmake总结
查看>>
数据加密插件
查看>>
linux后台运行程序
查看>>
win7 vs2012/2013 编译boost 1.55
查看>>
IIS7如何显示详细错误信息
查看>>
Android打包常见错误之Export aborted because fatal lint errors were found
查看>>
Tar打包、压缩与解压缩到指定目录的方法
查看>>
新手如何学习 jQuery?
查看>>