题目:输入一个整数,输出该数二进制表示中1的个数。

// 二进制中1的个数

#include <stdio.h>

int wrong_count_1_bits(int n) // 错误解法: 当n为负数时, n>>=1右移, 最高位补1, 陷入死循环
{
int count = ;
while(n)
{
if( n & )
++count;
n >>= ;
}
return count;
} int count_1_bits(int n) // 常规解法, 若sizeof(int)=4, 循环32次
{
unsigned int mask = ;
int count = ;
while(mask) // 循环32次后, mask变为0
{
if( mask & n )
++count;
mask <<= ;
}
return count;
} int perfect_count_1_bits(int n) // 高效解法, 若n含二进制位为1的位数为t, 则循环t次
{
int count = ;
while(n)
{
n = (n-) & n; // 执行该语句后, n的二进制表示中, 最右边的1被置为0, 其余各位不变, 也即是每循环一次, 消去n最靠右的1
++count;
}
return count;
} int static_table_count_1_bits(int n) // 静态表法
{
int table[] =
{
, , , ,
, , , ,
, , , ,
, , ,
}; int count = ;
while (n)
{
count += table[n &0xf] ;
n >>= ;
}
return count ;
} int main(void)
{
printf("sizeof(int)=%d\n",sizeof(int));
printf("%d\n",0x0fffff73); // 非负数正常; 负数(如0xffffff73)会导致程序在wrong_count_1_bits函数处陷入死循环
int count1 = count_1_bits(0x0fffff73);
int count2 = perfect_count_1_bits(0x0fffff73);
int count3 = wrong_count_1_bits(0x0fffff73);
int count4 = static_table_count_1_bits(0x0fffff73);
printf("count1=%d,count2=%d,count3=%d,count4=%d\n",count1,count2,count3,count4); return ;
}

关键点:把一个整数减去1之后再和原来的整数做按位与运算& ,得到的结果相当于把整数的二进制表示中的最右边一个1变成0。

相关题目1:用一条语句判断一个整数是不是2的整数次方

if( (n-1)&n == 0 ) printf("Yes\n");

相关题目2:输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。

步骤1:求这两个数的异或 t = m^n;

步骤2:统计异或结果t的二进制表示中1的个数,即为需要改变的位数。

相关题目3:二进制中0的个数

方法1:上面常规解法中,改成 if( n^mask == 1 )  ++count;

方法2:先使用上面某种方法求得“二进制中1的个数”,间接求解:sizeof(int)*8 - 1的个数

剑指Offer:二进制中1的个数的更多相关文章

  1. leetcode 338. Counting Bits,剑指offer二进制中1的个数

    leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种 ...

  2. 剑指Offer 二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.   思路: 如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原 ...

  3. 剑指Offer——二进制中1的个数

    题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 加入一个数的二进制位是XXX...XXX1000...000,那么这个数减去1,就会变成XXX...XXX0111 ...

  4. 剑指offer——二进制中1的个数(c++)

    题目描述实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如,把9表示成二进制是1001,则输出为2 常规解法首先把n和1做位运算,判断n的最低位是不是1,然后把1左移一位得到2,再把n和2 ...

  5. 剑指Offer08 二进制中1的个数

    /************************************************************************* > File Name: 08_NumOf1 ...

  6. 剑指offer中二进制中1的个数

    容易想到的是将n一位一位的和1进行比较,产生如下代码 但是这样的话会出下面的问题 那么就是原数据不动,将1依次移动进行比较有如下的代码 一种更简单的方法是: 这样做的思路是 总而言之

  7. 剑指offer--13.二进制中1的个数

    就是猜测试数据没有负数,哈哈 ----------------------------------------------------------------- 时间限制:1秒 空间限制:32768K ...

  8. 剑指Offer-11.二进制中1的个数(C++/Java)

    题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 将数字和1先做与运算,然后将1右移一位,现在是判断数字的第二位是不是1,这样循环的做下去即可.也可以转换成字符串再统计 ...

  9. 9-剑指offer: 二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 代码 class Solution { public: int NumberOf1(int n) { if(n==0) re ...

  10. 剑指offer15 二进制中1的个数

    题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1.因此,如果输入9则函数输出2. int Number(int n) { ; while ...

随机推荐

  1. .NET基础之迭代器

    使用foreach循环是有IEnumerator接口来实现的,IEnumerator即实现了迭代器,在foreach中如何迭代一个集合arrayList呢? 调用arrayLis.GetEnumber ...

  2. LINQ to XML学习笔记

    一.XML基础知识 1.XML:可扩展标记语言 Extensible Markup Language ,提供了一种保存数据的格式,数据可以通过这种格式很容易地在不同的应用程序之间实现共享. 2.使用X ...

  3. multimap和multiset 认知和使用

    之前只是在C++ Primer里面看过关联容器,可能因为没有实际用过,只是看看,所以导致用的时候并不熟悉: 在这之前,map和set的特性应该要了解,map是关联数组,也就是由键值对组成的,而set只 ...

  4. 1052: [HAOI2007]覆盖问题 - BZOJ

    Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小 ...

  5. P​H​P​ ​5​.​3​连​接​s​q​l​ ​s​e​r​v​e​r​ ​2​0​0​8​ ​R​2

    我的机器为: xp sp3 sql server 2008 developer apache 2.2.2 php 5.3  从5.3开始,php就不再提供mssql.dll了,所以要php连接sql  ...

  6. (转)关于Struts 2 拦截器参数丢失问题

    from:http://www.cnblogs.com/huzx/archive/2011/06/09/2076328.html 今天在做用户的登陆认证的时候出现的问题. 在传参数的时候,发现参数丢失 ...

  7. Flume学习——BasicChannelSemantics

    public class MemoryChannel extends BasicChannelSemantics public abstract class BasicChannelSemantics ...

  8. MFC的dll中控制资源问题

    有程序EXE和DLL,其中DLL中有1个函数用来显示对话框,被EXE调用.当EXE和DLL都为Release或Debug时,没有任何问题,但EXE为Release.DLL为Debug时,就会出错.该D ...

  9. 1.Getting Started with ASP.NET MVC 5

    Getting Started Start by installing and running Visual Studio Express 2013 for Web or Visual Studio ...

  10. aop aspect

    所以“<aop:aspect>”实际上是定义横切逻辑,就是在连接点上做什么,“<aop:advisor>”则定义了在哪些连接点应用什么<aop:aspect>.Sp ...