您的位置:首页 > 编程语言 > C语言/C++

用C语言编写一个函数返回参数二进制中 1 的个数(3种方法)(谷歌笔试题)

2017-07-29 18:00 549 查看
比如: 15       0000 1111       4 个 1

程序原型:

int  count_one_bits(unsigned int value)

{

       // 返回 1的位数

}

1.用模2除2的方法

(1)正数

11

//00000000 00000000 00000000 00001011--11的二进制

//11%2==1 //有1

//11/2=5  //00000000 00000000 00000000 00000101--5的二进制,尾部丢掉一个1

//5%2==1  //有1

//5/2==2  //00000000 00000000 00000000 00000010--2的二进制,尾部丢掉一个1

//2%2==0  //没有1了,跳过末尾的0,继续往前找,看还有没有1

//2/2==1  //00000000 00000000 00000000 00000001--1的二进制,尾部丢掉一个1

//1%2==1  //还有1

//1/2==0  //00000000 00000000 00000000 00000000--0的二进制,尾部丢掉一个1,彻底没有1了

test.c

#include<stdio.h>
int count_one_bits(unsigned int n)
{
int count = 0;
while (n!=0)//二进制数中必有1
{
if (n % 2 == 1)//二进制中发现1
{
count++;
}
n = n / 2;//去掉末尾的一个1
}
return count;
}
int main()
{
int num = 11;
int ret = count_one_bits(num);
printf("ret=%d\n", ret);
system("pause");
return 0;
}

运行界面







(2)负数

unsigned只是从语言上看的,而在内存里只看地址

test.c


#include<stdio.h>
int count_one_bits(unsigned int n)//看待-1是2^32-1
{
int count = 0;//计数
while (n!=0)//二进制数中必有1
{
if (n % 2 == 1)//二进制中发现1
{
count++;
}
n = n / 2;//去掉末尾的一个1
}
return count;
}
int main()
{
int num = -1;//存的是补码,有符号
//10000000 00000000 00000000 00000001---原码
//11111111 11111111 11111111 11111110---反码
//11111111 11111111 11111111 11111111---补码
int ret = count_one_bits(num);
printf("ret=%d\n", ret);
system("pause");
return 0;
}

运行界面




2.右移的方法

*与1按位与,最低位为0,代表原数的最低位为0;[b]最低位为1,代表原数的最低位为1。[/b]

[b]*>>箭头向右,右移操作符。[/b]

11

//00000000 00000000 00000000 00001011--11的二进制

//00000000 00000000 00000000 00000101--5的二进制,向右移一位,前面补上符号位(正0负1)。

test.c


#include<stdio.h>
int count_one_bits(unsigned int n)//看待-1是2^32-1
{
int count = 0;//计数
int i = 0;
for (i = 0; i < 32; i++)//32位平台上
{
if ((n & 1) == 1)//==优先于&
{
count++;
}
}
n = n >> 1;//在没赋值之前表达式结果为5,但n仍为11.
return count;
}
int main()
{
int num = 11;
int ret = count_one_bits(num);//返回值接受
printf("ret=%d\n", ret);
system("pause");
return 0;
}

3.n&(n-1)的方法(较优解,即会得分解)



11

//00000000 00000000 00000000 00001011--11的二进制

//00000000 00000000 00000000 00001010--10的二进制

//00000000 00000000 00000000 00001010--按位与,10,去掉结尾的1

//00000000 00000000 00000000 00001001--9的二进制

//00000000 00000000 00000000 00001000--按位与,8,去掉结尾的1

//00000000 00000000 00000000 00000111--7的二进制

//00000000 00000000 00000000 00000000--按位与,0,去掉结尾的1

执行了3次,就有3 个1。

test.c


#include<stdio.h>
int count_one_bits(unsigned int n)//看待-1是2^32-1
{
int count = 0;//计数
while (n!=0)//在n!=0之前,n = n&(n - 1)被执行几次,就有几个1.
{
count++;
n = n&(n - 1);//去掉1
}
return count;
}
int main()
{
int num = 11;
int ret = count_one_bits(num);
printf("ret=%d\n", ret);
system("pause");
return 0;}

*注意:要正数、负数都代入进行测试。

*********************************************************亮点*******************************************************            
 
a22c
     


 PS:能不能判断一个数字是2^n   ----------用n&(n-1)=0

期待各位大神的批评指正    0^_*0  

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐