美文网首页
算法 | 如何把一个int型二进制数的最右侧的1提取出来?

算法 | 如何把一个int型二进制数的最右侧的1提取出来?

作者: 在中国喝Java | 来源:发表于2022-12-29 09:37 被阅读0次

前言

本文主要介绍如何把一个int型二进制数的最右侧的1提取出来,也就是只保留该int型数对应的二进制最右侧的1,其他的都变为0,并返回对应的10进制数字。

现有个数num=112256700,这个num对应的二进制为00000110101100001110011010111100,要求把这个数的二进制最右侧的1保留,其他的位置全部变为0,也就是变为00000000000000000000000000000100,变更后的二进制数对应的十进制为4。

思路分析

方法一

此方法为比较传统的方法,也就是先把num这个是转为二进制形式,放到一个数组中,然后遍历数组,找到最右侧的1,记录1的位置,然后转成10进制形式。

此方法理解起来简单、实现也简单,但是没有什么技术可言,也不够优雅,不推荐。

方法一代码实现

public class Code16_FindRightOne {
    public static int getRightOne(int num) {
        int[] arr = new int[32];
        for (int i = 31; i >= 0; i--) {
            arr[i] = (num & (1 << i)) == 0 ? 0 : 1;
        }
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 1) {
                res = i;
                break;
            }
        }
        return (int) (Math.pow(2, res));
    }
    public static void main(String[] args) {
        int rightOne = getRightOne(112256700);
        System.out.println(rightOne);
    }
}
复制代码
image.gif

看下运行结果为4。

方法二

此方法,利用了二进制的特性,可以非常简单的实现这个功能,先看下解决思路。

要保留左右侧的1,把其他位置都变为0,首先想到的是位运算,再来看下位运算的几个特性:

与&:两边都为1结果才为1,否则为0。

或|:两边有一个为1结果就为1,都为0时才为0。

异或^:相同为0,不同为1。

我们的目的是,把最右侧1左边的数,全部变为0,按照位运算来看,相与操作最为可能,只要把1左边的数取反再与原来的数相与就可以了。

如果把num取反,左边的数是解决了,那右边的数呢?右边的数也取反了,怎么把他还原回来呢?

先看个例子,比如一个二进制为000101000100,这个二进制取反后为111010111011,现在就差怎么把011变为100了,这么一看就简单了,把011加上1不就好了?111010111011 + 1 = 111010111100。让这两个数再进行相与就能保留最右侧的1了。

也就是,把原来的数numnum取反加1进行相与即可。

还记得取反加1又可以怎么表示吗?对了,num取反加1又可以表示为负数即-num

方法二代码实现

来看下代码吧。

public class Code17_FindRightOne {
    public static void printBinary(int num) {
        for (int i = 31; i >= 0; i--) {
            System.out.print((num & (1 << i)) == 0 ? "0" : "1");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        printBinary(112256700);
        printBinary(112256700 & -112256700);
        System.out.println(112256700 & -112256700);
    }
}
复制代码
image.gif

输出结果:

00000110101100001110011010111100
00000000000000000000000000000100
4
复制代码
image.gif

可以看到运行结果和方法一是一样的,说明方法二的代码功能实现也是正确的。

为了查看方便,我把原来的数以及两个数相与后的结果的二进制形式也打印了出来。从上面结果来看,是不是把最右侧的1保留下来了呢?

总结

从上面两个方案来看,方法二使用位运算比方法一简单的太多了,仅仅简单的一行代码就把功能给实现了,而且在效率方面也远比方法一高的多。

把一个数的二进制最右侧的1提取出来,在很多算法题目中会经常遇到,这里只是简单的介绍了下如何实现,后面会介绍更多使用此方法的案例。

当然实现方法有很多种,如果你有更好的办法,欢迎在评论区留言交流

相关文章

  • 编程之美之"二进制数中1的个数"

    解法1 我们希望算法的复杂度只和二进制中1的个数有关。 如何只对二进制数中的1进行操作呢? 给定一个数: a = ...

  • 算法题:搜索两条单身狗

    技术群里有人提出一个算法题:一个Int型数组,里面的每一个数都是成双成对的,只有一个数是单身狗,找出这个数,算法复...

  • & 、|、&&、||四种运算符

    int x = 64; //x等于二进制数的01000000 int y = 70; //...

  • 338. Counting Bits

    key tips 动态规划 + 删除int最右侧比特位 algorithm 获取a 二进制表示下,删除最右侧比特位...

  • 浮点运算-精读丢失的原因和解决办法:

    首先我们要搞清楚下面两个问题: (1) 十进制整数如何转化为二进制数 算法很简单。举个例子,11表示成二进制数: ...

  • 数字的二进制的1的个数

    最直观的方法是把一个数的二进制,一个一个的计数。但是二进制数有巧算,代码如下: 其依据是n & (n -1),能已...

  • 数据类型

    位(bit) 一位代表一位二进制数 字节(byte) 1字节=8位二进制数 -128 ~ 127 int8 1个...

  • 进制转换

    java中int型占4个字节, 一个字节8位,共计32位int型取值范围是[-2^31, +2^31-1]最大的数...

  • 二、面试总结(二)

    1 手写ArrayList2 手写进制转换算法,求出一个数的二进制数1的个数3 JAVA基础 equals和==4...

  • Python基础(三): 数值和布尔

    一、数值 1. 表现形式 整数: int二进制: 0b + 二进制数(0, 1), 例如: 0b1010八进制: ...

网友评论

      本文标题:算法 | 如何把一个int型二进制数的最右侧的1提取出来?

      本文链接:https://www.haomeiwen.com/subject/bshtcdtx.html