整数的二进制表达式中有多少个1

* 无符号右移以为,检查右边的bit是否为1来统计, 要循环32次

* 如果只有1个1的情况 n & (n-1) == 0

* 平行算法 归并

 <?php
/**
 * Created by PhpStorm.
 * User: Mch
 * Date: 8/10/18
 * Time: 23:27
 * 整数的二进制表达中有多少个1
 */
class CountOne {
    public static function count1(int $n) : int {
        $res = 0;
        while ($n !== 0) {
            $res += $n & 1;
            $n >>=1;
        }
        return $res;
    }

    public static function count2(int $n) : int {
        $res = 0;
        while ($n !== 0) {
            $n &= ($n-1);  // 抹掉最右边的1
            $res++;
        }
        return $res;
    }

    /**
     * e.g. n = 0100 0100
     * BEGIN
     * n & (~n+1) = 0000 0100
     * n - (n&(~n+1)) = 0100 0000
     * n = 0100 0000
     * n & (~n+1) = 0100 0000
     * n - (n&(~n+1)) = 0
     * END
     * @param int $n
     * @return int
     */
    public static function count3(int $n) : int {
        $res = 0;
        while ($n !== 0) {
            $n -= $n & (~$n +1 ); // 得到n中最右侧的1
            $res++;
        }
        return $res;
    }

    public static function count4(int $n) : int {
        $n = ($n & 0x55555555) + (($n>>1) & 0x55555555);
        $n = ($n & 0x33333333) + (($n>>2) & 0x33333333);
        $n = ($n & 0x0f0f0f0f) + (($n>>4) & 0x0f0f0f0f);
        $n = ($n & 0x00ff00ff) + (($n>>8) & 0x00ff00ff);
        $n = ($n & 0x0000ffff) + (($n>>16) & 0x0000ffff);
        return $n;
    }
}


test:

// test
echo CountOne::count1(192).PHP_EOL;  // 2
echo CountOne::count2(192).PHP_EOL;  // 2
echo CountOne::count3(192).PHP_EOL;  // 2
echo CountOne::count4(192).PHP_EOL;  // 2

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/81571364