例如:f(11) = f(1011) = 20(1,10,11,100,101,110,111,1000,1001,1010,1011)
思路:先考虑第一位上的1(第几位一律从右侧数起),第一位上的1是每两个数出现1次,因此可以先计算11/2=5,然后对于11%2=1的部分,由于等于1,因此出现了一次1,故第一位上共出现了6次1;再考虑第二位,这一位上是每4个数出现2次1,先计算11/4*2=4,对于11%4=3的部分,只有在10-11之间会出现2次1,因此第二位上出现了6次1;第三位,(11/8*4)+0=4,第四位,0+(11-7)=4。因此f(1011)=10100=20。
总结一下:设index是二进制的位数(从0开始,依次递加),factor是2的整数次方(从2开始,依次递乘2),
factor = 2*(index+1)
index上出现1的次数为n/factor + 0(如果n%factor < factor/2)或者n%factor-factor/2+1(如果n%factor >= factor/2)
#include <stdio.h>
int NumsOf1(int n)
{
int count = 0;
int factor = 2;
int a, b, c;
int index = 0;
do
{
a = n/factor;
b = n%factor;
c = a*(factor/2);
count += c;
if(b >= factor/2)
{
count += b-factor/2+1;
}
factor *= 2;
index++;
}while(a != 0);
return count;
}
int main()
{
int n;
printf("输入n的值:\n");
scanf("%d",&n);
int count = NumsOf1(n);
printf("从1到%d的二进制正数中1出现的次数%d\n",n,count);
return 0;
}