求一个数二进制形式时最低为 1 的位

博客介绍了如何在O(1)时间内找到一个数二进制表示中最低位为1的位。通过位操作的技巧,以Python为例,详细解释了算法分析和代码实现,证明了该方法的高效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解

在 O(1) 内求一个数二进制形式时最低为 1 的位

例如 12 的二进制形式 1100,则 12 二进制形式时最低为 1 的位为倒数第 3 位。

如果我们从最低位向最高位一位一位判断的话,时间复杂度为 O(n),显然是无法满足要求的。

O(1) 方法

既然常规途径不符合要求,我们就要考虑一些技巧性的东西来帮我们寻找答案。 我首先想到的是位操作。关于位操作你可以参考一下我之前的一篇博客绝对值函数(位操作法)。基本上所有的高级语言都提供了对位操作的支持,由于最近我在学习 Python,所以这次我就尝试用 Python 来解决这个问题。

# -*- coding: utf-8 -*-
# python 2.7.3
# lob.py 	2014/06/20
# author:	sfyumi
# email:	ieatyumi@163.com
import math
#least one bit
def lobof(number): 
    num = ~number
    num += 1
    num = num^number
    num =~ num
    num += 1
    lob = int(mat
<think>我们需要计算一个正整二进制表示中1的个。常见的方法有迭代检查每一、利用 n & (n-1) 消除最低位1等。 这里我将使用两种方法实现,并解释它们。 方法1:循环检查每一 我们可以循环32次(假设int是32),每次检查最低位是否为1,然后右移一。 方法2:利用 n & (n-1) 这个操作可以将n的最低位1变为0。因此,我们不断进行这个操作直到n为0,操作的次就是1的个。 下面用C语言实现这两种方法。</think>以下是用C语言实现正整二进制形式1的个的两种高效方法: ### 方法1:使用操作 `n & (n-1)` ```c #include <stdio.h> int count_ones(unsigned int num) { int count = 0; while (num) { num &= (num - 1); // 清除最低位1 count++; } return count; } int main() { unsigned int num = 13; // 二进制: 1101 printf("字 %u 的二进制1的个: %d\n", num, count_ones(num)); return 0; } ``` **代码解释**: 1. `num &= (num - 1)`:关键操作,每次清除最低位1(如 `1101 & 1100 = 1100`) 2. 循环执行直到 `num=0`,循环次即为1的个 3. 间复杂度:**O(k)**(k为1的个),效率优于逐检查 ### 方法2:使用查表法(空间换间) ```c #include <stdio.h> // 预计算0-255所有值的1的个 void precompute(int table[]) { for (int i = 0; i < 256; i++) { table[i] = (i & 1) + table[i / 2]; } } int count_ones_fast(unsigned int num) { static int table[256] = {0}; static int initialized = 0; if (!initialized) { precompute(table); initialized = 1; } // 分段查表:按8分段处理 return table[num & 0xFF] // 最低8 + table[(num >> 8) & 0xFF] // 次低8 + table[(num >> 16) & 0xFF] // 高8 + table[num >> 24]; // 最高8 } int main() { unsigned int num = 255; // 二进制: 11111111 printf("字 %u 的二进制1的个: %d\n", num, count_ones_fast(num)); return 0; } ``` **代码解释**: 1. **预计算表**:提前计算0-255所有字的1的个并存储 2. **分段处理**:将32分成4个8段,分别查表后和 3. 间复杂度:**O(1)**(仅需4次查表操作) 4. 空间复杂度:256字节(可接受) ### 性能对比 | 方法 | 间复杂度 | 适用场景 | |--------------|------------|------------------------| | `n & (n-1)` | O(k) | 通用,1较少效率高 | | 查表法 | O(1) | 需要极致性能的场景 | **注意事项**: - 使用`unsigned int`确保处理的是无符号 - 查表法首次调用会初始化表,后续调用无开销 - 两种方法均支持0xFFFFFFFF(32最大整
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值