腾讯面试题——返回一个数二进制序列中1的个数

题意:要求返回一个数二进制序列中1的个数

           要获取一个数的二进制序列1:利用连除法将序列依次逆序输出。2:利用位运算直接从内存中调用。

方法一:连除法

int  count_bits_one(int unsigned num)
{
int count = 0;
while(num)
{
if(num%2==1)   //利用将十进制数字转化为二进制数字的基本方法连除法依次得出二进制序列
{count++;}    //      每一位的值并判断其是否为1。
num=num/2;
}
return count;
}

注意:使用该方法统计时,需在函数定义时标注其为无符号参数int  count_bits_one(int unsigned num);

             eg:当num=-1时,(-1)!=1,进入while循环但(-1)%2=0;所以return count=0,与正确的值32不符。

                      为避免输入负值出错的状况,需将形参定义为无符号型。



方法二:按位遍历法

int  count_bits_one(int unsigned num)
{
int count = 0;
int i = 0;
for(i = 0;i<32;i++)
{
if(num&1==1)   //利用位运算符&从内存中读取变量的二进制序列并依次与1相与;
{count++;}
num = num>>1;  //使num的二进制序列(高位丢弃,低位补0)按位右移
}
return count;
}

eg: 11      0 0 0 0 1 0 1 1  —>  0 0 0 0 0 1 0 1       —>     0 0 0 0 0 0 1 0         —>      0 0 0 0 0 0 0 1       —>    0 0 0 0 0 0 0 0

           1  &  0 0 0 0 0 0 0 1           0 0 0 0 0 0 0 1                  0 0 0 0 0 0 01                      0 0 0 0 0 0 0 1                  0 0 0 0 0 0 01

相与结果:1 1 0 1 




方法三:num=num&(nm-1)循环

int  count_bits_one(int unsigned num)
{
int count = 0;
while(num)
{
count++;
num=num&(nm-1);    //用于计算一个二进制序列中1的个数,即有几个1函数就循环几次;
}
return count;
}

eg    13:        1 1 0 1

         12  &    1 01 0

                      1 1 1 0

              &      1 1 0 1

                      1 1 0 0

               &     1 0 1 1

                      1 0 0 0    //11的二进制序列中含有3个1,循环3次;

num=num&(nm-1)也可用于判断一个数是否是2的n次方即:(num=num&(nm-1)==1)? yes:no;

              

四.输出二进制序列并计算1的个数

int count_one_bits (unsigned int avlue)
 {
  int i = 0;
  int count = 0;
  int arr[16];


   while(avlue>0)
  {
     arr[i] = avlue%2;
	 avlue = avlue/2;
	 i++;
	 }     //连除法获取二进制序列
  
  for(i--;i>=0;i--)
  {printf("%d ",arr[i]);   //依次逆序输出二进制序列
   if(arr[i]==1)
	 {count = count+1;}
   }
  return count;
 }



猜你喜欢

转载自blog.csdn.net/erica_ou/article/details/52604003