Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16246
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-08-14 08:56
文章分类
文章存档

2016年(2)

2015年(27)

我的朋友
最近访客

分类: C/C++

2015-08-14 08:59:08

Q: 对于一个字节的(8bit)无符整形变量,求其二进制表示中“1”的个数,要求算法执行效率尽可能高。

A

#include

using namespace std;

 

int count1(unsigned char v);

int count2(unsigned char v);

int count3(unsigned char v);

int count4(unsigned char v);

int count5(unsigned char v);

 

int main()

{

         unsigned char v = 7;

         cout<

 

         return 0;

}

/**

*解法1

*除法,当除以21时,则最低位为1

*时间复杂度为O( log2(v) ),log2(v)为二进制的位数

**/

int count1(unsigned char v)

{

         int num = 0;

         while(v)

         {

                   if(1 == v%2)

                            num++;

                   v = v / 2;

         }

         return num;

}

/**

*解法2

*移位操作,与0x01相与,判断最后一位是否为1,然后右移1

*移位操作的效率要比除法运算的高

*时间复杂度为O( log2(v) ),log2(v)为二进制的位数

*/

int count2(unsigned char v)

{

         int num = 0;

         while(v)

         {

                   num += v & 0x01;

                   v >>= 1;

         }

         return num;

}

/**

*解法3

*将二进制数减1后与原数相与,得到的结果比原数少一个1

*由此可以只通过1的个数次运算得到结果

*时间复杂度为O(M),Mv1的个数

*/

int count3(unsigned char v)

{

         int num = 0;

         while(v)

         {

                   v &= v-1;

                   num++;

         }

         return num;

}

/**

*解法4

*使用分支操作,罗列所有的情况,空间换取时间

*但次法效率可能要低于解法23,因v取值不同,进行比较运算

*的次数不同,最差情况要比较255

*/

int count4(unsigned char v)

{

         int num = 0;

         switch(v)

         {

         case 0x00:

                   num = 0;

                   break;

         case 0x01:

         case 0x02:

         case 0x04:

         case 0x08:

         case 0x10:

         case 0x20:

         case 0x40:

         case 0x80:

                   num = 1;

                   break;

         case 0x03:

         case 0x06:

         case 0xc:

         case 0x18:

         case 0x30:

         case 0x60:

         case 0xc0:

                   num = 2;

                   break;

         //...

         }

         return num;

}

/**

*解法5

*查表法,将256种情况的结果直接存在数组中,通过空间换取时间

*算法复杂度为O(1)

*/

 

int count5(unsigned char v)

{

         int countTable[256]=

         {

                   0,1,1,2,1,2,2,3,1,2,2//...

         };

         if(v<0 && v>255)

                   exit(1);

         return countTable[v];

}

阅读(119) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~