我正在尝试找出一个大的十进制数(十进制数可以达到1000000)的二进制形式中1的数量。
我尝试了这段代码:
while(sum>0)
{
if(sum%2 != 0)
{
c++; // counting number of ones
}
sum=sum/2;
}
我希望能有一个更快的算法,因为对于大量小数输入来说,时间太长了。请给我推荐一个高效的算法。
#ifdef __APPLE__
#define NAME(name) _##name
#else
#define NAME(name) name
#endif
/*
* Count the number of bits set in the bitboard.
*
* %rdi: bb
*/
.globl NAME(cpuPopcount);
NAME(cpuPopcount):
popcnt %rdi, %rax
ret
当然,您需要先测试CPU是否支持:
/*
* Test if the CPU has the popcnt instruction.
*/
.globl NAME(cpuHasPopcount);
NAME(cpuHasPopcount):
pushq %rbx
movl $1, %eax
cpuid // ecx=feature info 1, edx=feature info 2
xorl %eax, %eax
testl $1 << 23, %ecx
jz 1f
movl $1, %eax
1:
popq %rbx
ret
这里是C语言的一种实现:
unsigned cppPopcount(unsigned bb)
{
#define C55 0x5555555555555555ULL
#define C33 0x3333333333333333ULL
#define C0F 0x0f0f0f0f0f0f0f0fULL
#define C01 0x0101010101010101ULL
bb -= (bb >> 1) & C55; // put count of each 2 bits into those 2 bits
bb = (bb & C33) + ((bb >> 2) & C33);// put count of each 4 bits into those 4 bits
bb = (bb + (bb >> 4)) & C0F; // put count of each 8 bits into those 8 bits
return (bb * C01) >> 56; // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}
GNU C编译器运行时包含一个“内置函数”,可能比上面的实现更快(它可能使用CPU的popcnt指令,但这取决于具体实现):
GNU C编译器运行时包含一个“内置函数”,可能比上面的实现更快(它可能使用CPU的popcnt指令,但这取决于具体实现):
unsigned builtinPopcount(unsigned bb)
{
return __builtin_popcountll(bb);
}
在我的C++棋类库中,所有上述实现都用于popcount,在使用位板表示棋子位置时生成棋步是至关重要的。我使用函数指针,在库初始化期间设置它以指向用户请求的实现,然后通过该指针使用popcount函数。
谷歌可以提供许多其他的实现,因为这是一个有趣的问题,例如:http://wiki.cs.pdx.edu/forge/popcount.html。
在 C++ 中,您只需这样做。
#include <bitset>
#include <iostream>
#include <climits>
size_t popcount(size_t n) {
std::bitset<sizeof(size_t) * CHAR_BIT> b(n);
return b.count();
}
int main() {
std::cout << popcount(1000000);
}
size_t
不一定是32位。而且1字节不一定意味着8位。因此,我修改了答案。 - Nawaz有许多方法。易于理解且相当快速的方法是Brian Kernighan的方法:
unsigned int v = value(); // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
for (c = 0; v; c++)
。变量 v
没有初始化。 - Nawazv
应该包含我们想要计数位的值。 - Mike Seymour int number = 15; // this is input number
int oneCount = number & 1 ? 1 : 0;
while(number = number >> 1)
{
if(number & 1)
++oneCount;
}
cout << "# of ones :"<< oneCount << endl;
int count_1s_in_Num(int num)
{
int count=0;
while(num!=0)
{
num = num & (num-1);
count++;
}
return count;
}
std::count
:) - chris