zoukankan      html  css  js  c++  java
  • Rocket

     
    介绍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)
    }
     
     
  • 相关阅读:
    【ES6】数组的扩展——扩展运算符
    【ES6】函数的扩展
    菜鸡程序员是如何写代码的?
    我是技术总监,我出来求职,竟然找不到工作!
    为什么互联网公司天天都在招人?
    这个立冬,我线下面基了一位TMD高级专家,太牛逼了!
    太可怕了!有些码农为啥写代码,写到监狱里去了?
    56岁潘石屹生日当天宣布要学编程语言Python,网友:地产商来抢码农饭碗了!
    如何写出让同事无法维护的代码?
    hdu 1037 Keep on Truckin'
  • 原文地址:https://www.cnblogs.com/wjcdx/p/10669793.html
Copyright © 2011-2022 走看看