从JDK源码看二分思想

在查看JDK源码的时候,看到了Integer类中有一个方法numberOfLeadingZeros,这个方法的作用是计算目标值i(十进制)转换二进制(int类型长度为32位)数后左边共有多少位0,这个方法本身对编程来说用的不多,但其思想却值得我们好好学习一下。

其源码如下:

public static int numberOfLeadingZeros(int i) {
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;
        return n;
}

我们以1314520这个数字来查看二分思想,1314520转换为二进制为 00000000 00010100 00001110 11011000,所为二分就是把整体平均分为两部分。

第一步:

i >>> 16(右移16位),就只剩下00000000 00010100不为0,既然不为0零那剩下的被移走的那16位,也就是右边16位,就没什么用了,继续分析剩下的16位,即左边的16位。

第二步:

i >>> 24(右移24位),实际上是将左边的16位二分,来进行分析,剩下00000000为0,这样就有了8位零,计数器n加8,此时n为9,左边8位为零那再分析左边8位就没意义了,目标数右移8位后,刚好将左边没意义的8位移走,继续分析右边8位。

第三步:

i >>> 28(右移28位),将剩下要分析的8位,也就是00010100二分,得到左边4位0001不为0,则继续分析左边4位

第四步:

i >>> 30(右移301位),将待分析的4位0001二分,知易行难00为0,计数器n加2,此时n为11,同理,将i左移2位去掉已经分析过的为零的2位,然后再分析剩下的2位

第五步:

n -= i >>> 31,到这个时候只需要分析右边的1位就好了,如果为0则n不变,如果为1则n-1。等等,这里为零为什么不变,为1反而要减1,我们的理解不是应该为0则n+1,为1则n不变吗。原因很简单,那就是n的初始值为1而不是0。这里最后一位为0,故n不变,为11.
最终答案也就是11。

注意:

一、二分之后如果左边不为0则下一个要分析的目标是左边,如果为0则下一个要分析的目标是右边,怎样再下一次移动相同位数的时候,既可以分析左边,又可以分析右边呢,作者的做法就是,如果分析左边,则数字i不变,如果分析右边则将无用的左边移走然后赋值给i,具体的 i >>> 16 后有两种情况。1)左边为0,数字i右移16位,等下次i >>> 24位的时候分析的就是右边16位,2)左边不为0,则分析左边16位,i不变,等下次i >>> 24位的时候分析的就是左边16位。
二、二分后只用判断左边的位数就好,如果左边为0,则右边肯定不为0,因为左右合起来不为0;如果左边不为0,那右边为不为0没意义。

二分思想在编程的世界里用处还是很广泛的,如二分查找,效率还是挺高的。解释的有点详细(你也可以说是啰嗦),但目标只有一个就是让大家理解这个思想。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容

  • 你用柔美的言语 放飞心中的遐思 你用狼人的心态 奔跑在无尽的山野 你用奇妙的双手 书写着世界的沉浮 —————— ...
    远昔阅读 370评论 3 1
  • 前言 软件的使用上我一直有一种洁癖,一旦遇到带有广告和其他流氓行为的程序浑身不自在,有的时候不得不用它们就像吃了苍...
    Dogged_Ivan阅读 255评论 0 0