面试题 10

来源:互联网 发布:四大台柱 知乎 编辑:程序博客网 时间:2024/04/28 02:13

1 题目描述

计算数的二进制表示中的 1 的个数,例如把 9 表示成二进制是 1001,有 2 位是1.


2 解决方法

第一种方法:依次右移 n ,检查最右边一位是不是 1

int numberOf1(int n){    int count=0;    while(n){        if(n&1){            count++;        }        n=n>>1;    }    return count;}

存在问题,对于负数,此方法将导致无限循环,因为负数右移会在最左边用符号位 1 补齐,所以 n 永远不会等于 0,此方法不可行。

第二种方法,不移动 n,而是每次将 flag 左移一位,直到 flag 为 0 为止

int numberOf1_1(int n){    int flag=1;    int count=0;    while(flag){        if(n&flag){            count++;        }        flag=flag<<1;    }    return count;}

此方法可以实现,循环的次数等于整数二进制的位数,32 位的整数需要循环32次。

第三种方法:对于任意一个二进制形式的数存在以下规律

   10001000 - 1 = 1000 0 111

假设一个二进制数最右边第一个 1 位于第 m 位,那么减去 1 时, m 位变为 0 ,m 位左边不变,右边全部变为 1。此时我们将减 1 之后的数与原整数进行按位与运算,结果成功将第 m 位的 1 变成了 0。

int numberOf1_2(int n){    int count=0;    while(n){        count++;        n=n&n-1;    }    return count;}

二进制数中有多少个 1,方法将循环多少次,直到去掉所有的 1 ,使得原整数等于 0 。


3 其他应用

把一个整数减去 1 之后再和原来的整数作为运算,得到的结果相当于是把整数的二进制表示中的最右边一个 1 变成 0 。

应用 1 :用一条语句判断一个整数是不是为 2 的整数次方。如果一个数是 2 的整数次方那么那么它的二进制表示中有且只有一位是 1 。

void if2Power(int n){   if(n-1&n){        printf("\n%d 不是 2 的整数次方",n);   }else{        printf("\n%d 是 2 的整数次方",n);   }}

应用 2 :计算需要改变 m 的二进制表示中的多少位才能得到 n 。比如 10 的二进制表示为 1010 ,13 的二进制表示为 1101 需要改变 1010 中的 3 位 才能得到 1101。m ^ n 然后计算异或结果中 1 的个数。

int findDif(int m,int n){    int temp=m^n;    return numberOf1_2(temp);}

全部代码

#include<stdio.h>int numberOf1(int n){    int count=0;    while(n){        if(n&1){            count++;        }        n=n>>1;    }    return count;}  //此方法不可行int numberOf1_1(int n){    int flag=1;    int count=0;    while(flag){        if(n&flag){            count++;        }        flag=flag<<1;    }    return count;} //此方法可行,循环 32 次int numberOf1_2(int n){    int count=0;    while(n){        count++;        n=n&n-1;    }    return count;}   //此方法可行,循环次数为原整数二进制表示中 1 的个数//用一条语句判断一个整数是不是为 2 的整数次方void if2Power(int n){   if(n-1&n){        printf("\n%d 不是 2 的整数次方",n);   }else{        printf("\n%d 是 2 的整数次方",n);   }}//计算需要改变 m 的二进制表示中的多少位才能得到 n 。int findDif(int m,int n){    int temp=m^n;    return numberOf1_2(temp);}//测试用例void main(){    printf("%d",numberOf1(1));    printf("\n");    printf("%d",numberOf1_1(-1));    printf("\n");    printf("%d",numberOf1_2(-1));    if2Power(10);    if2Power(16);    printf("\n");    printf("%d",findDif(10,13));}
0 0