0


漫笔| &是啥,只需要用三行代码解百度的面试题

6c30f28b98334873848cb39dc42ccaf6.png

5c78359a7a514a249f0b57d9c85f5c67.png

🌕写在前面:


哈喽哈喽,这里是小戴~

趁着五一放假有什么想分享的吖?

我先来!(把手举得高高)虽然小戴假期只有3天,但还是和好姐妹去看了新上映的电影,嗦了常德最有名的米线,嘎嘎香~

0dbbf4ff868e4df1829da21d85ce9a2a.png

致敬每一份异地恋~

anyway,回到正题,今天是五四青年节,有梦就去追~

每个人都有自己想去做的事情,我也不例外嘻嘻,一起加油~猫猫冲💪💪

c6f8571248ab4e20aca053197cba6067.png

🥝1. 何为&?

按位与(&)是双目运算符

功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位都为1时,结果位才为1。在电脑中,数是以补码的形式存储的,参与位运算用数的补码形式


0fa9879e03044052a597944a9681bbc5.png

巧记:

都1才1

48dd3fb53b3741ec8d6a4df21d5b5a04.png

🥝2. 一些题目

计算一个数二进制中1的个数。

比如:15 0000 1111 4个1


99097407094541eebed2faff81dd3205.png

位运算可以直接操作整数二进制中的位

一个整数按位与1,返回的结果为1,表示该整数二进制最后一位是1,否则为0。

一次按位与1,只能判断一次。

一个整数,四个字节,32个比特位,若要计算整个数二进制有多少个1,需进行32次按位与1。


🍊2.1 方法一

Java:

public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n= sc.nextInt();
        int count=0;
        int i;
        for(i=0;i<32;i++){
            if(((n>>i)&1)!=0)
                count++;
        }
        System.out.println(count);
    }
}

C:

#include <stdio.h>
int main()
{
    int n;
    scanf("%d", &n);//输入一个数
    int count = 0;//计数
    int i;
    for (i = 0; i < 32; i++) 
    {
        if (((n >> i) & 1) != 0)
            count++;
    }
    printf("%d\n", count);//输出
    return 0;
}

此方法不管是什么数,都要进行32次按位与。

打颗栗子:

7的二进制形式是

0000 0111

7的二进制有3个1,数右移三次,左边补符号位,7早已经变成了0,7二进制中的1的个数已经计算完了,但循环没有结束,程序会继续运行。

为了节省时间和空间,从第4次循环开始是没有必要的,因此有了方法二的优化版本。

事物是不断发展的,程序也会在大家的思考和发现中不断迭代~

29ec965a25944082b4907304a9a4a206.gif

🍊2.2 方法二(优化版

Java:

public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int count=0;
        while(n!=0){
            if((n&1)!=0) {
                count++;
            }
            n=n>>>1;//无符号右移一次
        }
        System.out.println(count);
    }
}

方法二相较于方法一,**-1的二进制形式是全1**,-1向右移,左边补符号位1,n就一直不能为0,会陷入死循环。

所以n是无符号右移,无符号右移是Java中的一种特殊的运算符因为Java中没有无符号类型。无符号右移,不管是正数还是负数,左边都是补0。


🍊盛盛问:

那Java中有没有无符号左移呢?

因为左移是在后面补0. 而右移是在前面边补1或0. 有无符号是取决于数的前面的第一位是0还是1. 所以右移是会产生到底补1还是0的问题。而左移始终是在右边补,不会产生符号问题。 所以没有必要无符号左移<<<。. 无符号左移<<<和左移<<是一样的概念.——摘自百度

c5ce39e543914f76bc9981f1bb53cfe9.gif

🍊2.3 方法三(进阶版

public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int count=0;
        while(n!=0){
            n=n&(n-1);
            count++;
        }
        System.out.println(count);
    }
}

程序细分析:

de6277f5673d48f0844ab9e02dd56ea7.png

每一次 n&(n-1) 都会消除一个1,然后再将 n&(n-1) 赋值给n,

当n=0时,程序结束。

079c261168f349cfae8740004e2340aa.gif

🥝2. 百度面试题

判断一个数,是不是2的K次方。


public class test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int temp;
        temp=n&(n-1);
        if(temp==0){
            System.out.println(n+"是2的k次方");
        }
        else {
            System.out.println(n+"不是2的K次方");
        }
    }
}

程序细分析:

问:2的K次方有哪些数呢?

简单啊这题,仔仔细细想想,2的K次方不就是1、2、4、8、16...这些数吗?

这些数的二进制中只有一个1。

即 如果n是2的k次方,n&(n-1) 执行一次,n就变成了0,最后就输出就行。

5e01bc28cba24f73be5616c1c1acb4b5.png

🌕写在最后:


恭喜咱们又进步了一点点~

不管是学习还是各方面的,未来的路还很长,小戴和你一起走下去~

🎉欢迎关注🔎点赞👍收藏⭐️留言📝

066081a53bc44104b6178fa8519fb508.png

“人生就是拔旧萝卜和种新萝卜。”

📆本文首发时间:🌹2022年5月4日🌹

🆕最新更新时间:🎄2022年5月4日🎄


本文转载自: https://blog.csdn.net/weixin_60777483/article/details/124561743
版权归原作者 Anya-.- 所有, 如有侵权,请联系我们删除。

“漫笔| &amp;是啥,只需要用三行代码解百度的面试题”的评论:

还没有评论