关于比特为1的计数算法

原创 2007年10月03日 18:10:00

问题描述:

        给定一个32(2^n)比特的整数,用一个算法计算出其中包含的1的个数。

问题分析:

      对于该问题,最容易想到的算法就是穷举算法,对该整数的每个比特进行扫描计数,对于一个包含n比特的整数,该算法的时间复杂度为O(n),空间复杂度为O(1)。

算法如下(C语言):

int  count(unsigned int i)

{

    int count = 0;

    for(int j=0;j<32;j++)

   {

       if((i>>j) & 1)

            count++;

   }

  return count;

}

 

算法解析:

        该算法在最好和最坏情况下的复杂度一样,都为O(n), n为比特数。

 

第二种方法:

     对于第二种方法,其最坏复杂度和第一种一样,但最好的情况下为O(1),平均复杂度仅为第一种的一半。

算法(C语言):

   int count(unsigned int i)

  {

     int count = 0;

     while(i)

    {

     count++;

    i = i & (i-1);

     }

  }

 该算法仅对比特为1的进行计数,每次循环计算一个比特为1的位,该算法的时间复杂度还是O(n),但是效率比之第一种算法平均要快上一倍。

第三种算法:

 这种算法的时间复杂度为O(logN),还是先给出算法的描述,然后再进行分析。

算法(C语言):

 int count(unsigned int i)

{

    i = (i & 0x55555555UL) +(( i>>1) & 0x55555555UL);

    i = (i & 0x33333333UL) + ((i>>2) & 0x33333333UL);

    i = (i & 0x0F0F0F0FUL) + ((i>>4) & 0x0F0F0F0FUL);

   i = (i & 0x00FF00FFUL) + ((i>>8) & 0x00FF00FFUL);

   i = (i & 0x0000FFFFUL) + (i >>16) & 0x0000FFFFUL);

  return i;  

}

算法分析:

 该算法首先将32比特的整数分成16组,每两个相邻的比特分为一组,分组计算每组的比特为1的数量,

对于一个整数如:xyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxy,b分为两部分后,第一部分为i & 0x55555555UL,

第二部分为:(( i>>1) & 0x55555555UL),由于0X55555555UL的二进制为01010101010101010101010101010101b, 这样,用i与之进行与操作之后,相当于只是取了奇数部分的比特,结果为0y0y0y0y0y0y0y0y0y0y0y0y0y0y0y0yb,

而第二部分则先进行一个比特的移位之后,再进行一个与操作,结果为0x0x0x0x0x0x0x0x0x0x0x0x0x0x0x0xb,

(x和y为0或者1),然后把这两部分的结果相加,可以看出,0x + oy结果可能为00,01,10,  而这两比特中所保存的结果就是在原来的整数中xy部分的比特为1的个数。(如果1为1,y为0,则只有一个1比特,此时结果为01,同样,若x,y均为1,则结果为10,也是表示只有2个比特为1,其它为0或者1的情况同样成立),这样在结果i中保存16组(每组2比特)的1的个数,然后再将这个16组分成8组,每组四比特(即前面的2个2比特),将4比特中的前2比特进行移位与后两比特对齐,再进行相加,此时在结果4比特中的保存的就是这原来4比特中1的个数(因为前面的结果中每组2比特中最大为10,这样相加后,最大值为0100,表示的还是这4个比特中为1的个数,而且不会向前部分产生进位),然后再放大到8比特组,最后到16比特组,得到的结果就是该整数中比特为1的个数。

Shell中的一些常用特殊字符

1、关于$ $是个在shell中有多种使用方式的东东。不经常使用时,也是很容易忘记的一个特殊标识符,记录一下比较常用的几种用法:   $# : 获得脚本传入参数的个数。$? :  获...
  • opensure
  • opensure
  • 2015年05月25日 13:33
  • 2356

字节、字、位、比特,这四者之间的关系

1、位(bit) 来自英文bit,音译为“比特”,表示二进制位。位是计算机内部数据储存的最小单位,11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以...
  • yc1022
  • yc1022
  • 2014年09月03日 18:12
  • 4116

机器学习之奇异值分解之特征值(SVD)

MIT教授Gilbert Strang曾经称SVD为线性代数的绝对制高点,其在单机上实现就是一个很困难的问题,更何况于分布式?当然这里所指的实现并不是指能够做出来,而是指能够给社会带来真正贡献,毕竟算...
  • LZL939899727
  • LZL939899727
  • 2014年05月12日 12:28
  • 2935

GC系列:如何优化引用计数算法(1)

引言    标记-清除,标记-整理,复制式回收算法都是属于间接式的:先从根集合出发,遍历根集合图,找到存活的对象,再反向确定出死亡的对象。而引用计数算法则可以通过引用关系的创建和删除直接确定对象的存活...
  • FoolishAndStupid
  • FoolishAndStupid
  • 2017年06月03日 17:45
  • 398

《算法导论》第8章 线性时间排序 (1)计数排序

一种简单的实现是得到数组C,C[i]表示数组A中值为i的元素个数。 C = { 2, 0, 2, 3, 0, 1 }就表示两个0,两个2,三个3,一个5。 然后将这些数字依次存到数组B中。 ...
  • dc_726
  • dc_726
  • 2012年02月19日 15:32
  • 1605

基于计数排序求中位数问题的O(1)算法(Fraudulent Activity Notifications问题)

基于计数排序求中位数问题的O(1)算法(Fraudulent Activity Notifications问题)
  • qq_33938011
  • qq_33938011
  • 2017年02月10日 12:53
  • 395

深入理解Java虚拟机-(1)引用计数算法

Java虚拟机
  • qq_23851075
  • qq_23851075
  • 2016年10月21日 16:20
  • 224

一种是用视频客流计数算法

  • 2015年03月08日 20:41
  • 1.09MB
  • 下载

计数查找算法。docx

  • 2011年08月09日 12:22
  • 65KB
  • 下载

求32位无符号整数中比特为1的二进制位数

测试环境:       1、 Intel(R) core(TM) I5-2410M CPU@2.30GHz 2.30GHz 处理器;       2、操作系统:Win7;       3、开发环...
  • liuxuezong
  • liuxuezong
  • 2013年03月21日 17:58
  • 2006
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于比特为1的计数算法
举报原因:
原因补充:

(最多只允许输入30个字)