You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java递归函数问题求助:实现ones(int x)统计二进制1的个数

嘿,我来帮你搞定这个递归统计二进制1的个数的问题!要写出能适配任意int位数(16/32/64位)的ones(int x)函数,关键要解决负数右移的死循环问题和递归的终止逻辑,我给你两种清晰的实现思路:

思路一:基础递归(简单易懂,适配任意位数)

这是最直观的递归写法,核心是用无符号右移来避免负数高位补1导致的无限递归,完全不依赖int的具体位数。

实现代码

public class BitCounter {
    public static int ones(int x) {
        // 递归终止条件:x变成0时,二进制里已经没有1了
        if (x == 0) {
            return 0;
        }
        // 先判断最低位是否为1(x&1的结果是0或1),再加上右移后剩余部分的1的个数
        return (x & 1) + ones(x >>> 1);
    }

    // 测试用例
    public static void main(String[] args) {
        System.out.println(ones(5));      // 二进制101 → 输出2
        System.out.println(ones(-1));     // 全1的二进制 → 输出对应int位数(比如32位就是32)
        System.out.println(ones(0));      // 输出0
        System.out.println(ones(0b111000));// 二进制111000 → 输出3
    }
}

为啥能适配任意位数?

普通的带符号右移>>对负数会在高位补1,导致负数永远变不成0,直接陷入死循环。而**无符号右移>>>**不管原数是正还是负,都会把最高位补0,直到整个数变成0——不管int是16位还是64位,这个逻辑都能完美工作,完全不依赖具体位数。

比如-1的二进制是全1,无符号右移每次都会把最右边的1移走,直到所有位都变成0,递归次数正好等于int的位数,返回结果就是总位数,完全符合要求。

思路二:分治递归(高效进阶)

如果追求更高的统计效率,可以用分治的递归思路,把数字拆成小块分别统计1的个数,再合并结果。这种方法的递归层级更少,速度更快:

实现代码

public static int ones(int x) {
    if (x == 0) return 0;
    // 每两位一组统计1的个数
    x = x - ((x >>> 1) & 0x55555555);
    // 每四位一组合并结果
    x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
    // 每八位一组合并结果
    x = (x + (x >>> 4)) & 0x0F0F0F0F;
    // 继续合并更高位
    x = x + (x >>> 8);
    x = x + (x >>> 16);
    // 取最终结果(最多64位的话,结果不会超过64,所以用0x3F掩码足够)
    return x & 0x0000003F;
}

这个方法虽然看起来复杂,但本质还是递归的分治思想,而且同样适配任意int位数——因为不管位数多少,最终都会合并到最低位得到总数。

内容的提问来源于stack exchange,提问作者TheSavvyGirl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:32:15