统计十进制数的二进制表示中1的个数 ← 清华 邓俊辉

【题目描述】
统计十进制数的二进制表示中1的个数。

【算法分析】
虽然曾在 
https://blog.csdn.net/hnjzsyjyj/article/details/110148954 发过一篇关于“统计十进制数的二进制表示中1的个数”的博客,但本文实现了一种新的思路。此思路来源于清华大学邓俊辉版《数据结构》http://dsa.cs.tsinghua.edu.cn/~deng/ds/src_link/countones/countones_2.cpp.htm 中的内容。现分析如下:
● POW(x) 函数
自定义的 POW(x) 函数,运行后得到 2^x。

int POW(int x){
    return 1<

● MASK(x) 函数
自定义的 MASK(x) 函数,运行后得到以 2^x 个 0 及 2^x 个 1 相间的32位的二进制数。这是本文算法的一个重要核心点。

int MASK(int x){
    int t=POW(x);
    return ((unsigned long) -1)/(POW(t)+1);
}

其中,MASK(0)、MASK(1)、MASK(2)、MASK(3)、MASK(4)的值如下所示。

MASK(0) = 01010101010101010101010101010101(b) = 55555555(h)
MASK(1) = 00110011001100110011001100110011(b) = 33333333(h)
MASK(2) = 00001111000011110000111100001111(b) = 0f0f0f0f(h)
MASK(3) = 00000000111111110000000011111111(b) = 00ff00ff(h)
MASK(4) = 00000000000000001111111111111111(b) = 0000ffff(h)

● ROUND(x,c) 函数
自定义的 ROUND(x,c) 函数,运行时以 2^c 位为单位进行分组,相邻的组两两捉对累加给定的十进制数对应的二进制数中 1 的个数。这个函数是导致本文算法时间复杂度低的重要原因。

int ROUND(int x,int c){
    int u=x&MASK(c);
    int v=(x>>POW(c))&MASK(c);
    return u+v;
}

● 系统自带的求以 2 为底的 x 的对数 log2(x)

#include 
using namespace std;

int main() {
    int x;
    cin>>x;
    cout<


【算法代码】

#include 
using namespace std;

int POW(int x){
    return 1<>POW(c))&MASK(c);
    return u+v;
}

int countOnes(unsigned int n){
    n=ROUND(n,0);
    n=ROUND(n,1);
    n=ROUND(n,2);
    n=ROUND(n,3);
    n=ROUND(n,4);
    return n;
}
    
int main() {
    int x;
    cin>>x;
    cout<





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/110148954
https://dsa.cs.tsinghua.edu.cn/~deng/ds/src_link/countones/countones_2.cpp.htm

https://vimsky.com/examples/usage/cpp-programming_library-function_cmath_log2.html





 

你可能感兴趣的:(信息学竞赛,#,基础语法,位运算)