Thinking in Code!

一分耕耘\一分收获。
   相信自己->天道酬勤->把握人生!
                           --小易的BLOG

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

        这是个很简单的小编程题目,但频繁的出现在几场笔试中,自己便试着寻求他的多种实现方法,最后总结出了如下四个,思路大致相同:
1.通过模2判断最后一位是否为1,为1则COUNT++,然后除2(相当与将该数右移一位),循环;最终求出结果。
 实现如下:(C实现)
#include<stdio.h>
void main()
{
 int i,count=0;
 i=15;
 do
 {
  if((i%2)!=0)    //判断末尾是否为1
  {
   count++;         //末尾为1则count++
  }
  i=i/2;          //i除2,相当于右移一位
 }while(i>=1);
 printf("1的个数为%d\n",count);   //输出结果

}

2.通过与0x00000001进行&操作,判断该数末尾是否为1,为1则count++,然后右移一位,循环。
实现如下:
//这里我算的是signed int的2进制表示含1的个数,负数则转换成正数来计算
#include<iostream>
using namespace std;
int count(signed x);

int main()
{
 signed x;
 cout<<"please input a number:";
 cin>>x;
 cout<<count(x)<<endl;
 return 1;
}

int count(signed x)    //count函数对X含多少个1计数
{
 int a,i=0;
 a=1;
 if(x<0) x=-x;   //x小于0则把x转换成正数,也可以用x=~(x-1);替换 
 while(x){
  if(x&a){       //若x最低位为1,i++
   i++;
  }
          x>>=1;        //x向右移一位,x为正,向左边填0
 }
 return i;          //返回x中1的个数
}
3.使用bitset库。
实现如下:
#include <iostream>
#include <bitset>
using namespace std;

int main()
{
    int N;
    cin>>N;

    bitset<32> _N=N;     //定义一个32位的bitset类对象
    int num=0;
    for(int i=0;i<_N.size();i++)    
        if(_N[i])                    //循环判断_N的每位是否为1
            num++;               //计数
    cout<<num<<endl;

    return 0;
}

4.最后这个方法是最奇妙的,因为它没有用循环来做,是我从网上搜到的,算法思想我自己也没搞明白,先贴出来。
实现如下:
int count(unsigned x)
{
  x = x - ((x >> 1) & 0x55555555);  //保留x奇数数位(1、3、5..)上的1
  x = (x & 0x33333333) + ((x >> 2) & 0x33333333); //
  x = (x + (x >> 4)) & 0x0F0F0F0F;
  x = x + (x >> 8);
  x = x + (x >> 16);
  return x & 0x0000003F;
}

有明白的朋友也跟我解释下。

posted on 2008-03-28 21:56  Preboy  阅读(2400)  评论(1编辑  收藏  举报