【小白笔记】将十进制数(Decimal)转换为二进制数(Binary),并计算二进制表示中“1”的个数

使用Python实现一个函数,用于将十进制数(Decimal )转换为二进制数(Binary),并计算二进制表示中"1"的个数。


Python 实现

这里提供三种不同的 Python 实现方法:

方法一:使用 Python 内置函数 bin()count() (最简洁)

Python 的内置函数 bin() 可以直接将整数转换为以 '0b' 开头的二进制字符串,然后使用字符串的 count() 方法计算 '1' 的数量。

python 复制代码
def count_ones_in_binary_builtin(decimal_num):
    """
    使用 Python 内置函数 bin() 和 count() 计算十进制数转换为二进制后 1 的个数。

    Args:
        decimal_num (int): 要转换的十进制非负整数。

    Returns:
        int: 二进制表示中 1 的个数。
    """
    if decimal_num < 0:
        # 通常计算非负整数,如果需要处理负数,则需要考虑补码表示
        # 这里仅处理非负整数,可以根据实际需求调整
        return "输入必须是非负整数"

    # 1. 使用 bin() 转换为二进制字符串,例如 13 -> '0b1101'
    binary_string = bin(decimal_num)

    # 2. 使用 count('1') 计算 '1' 的个数
    ones_count = binary_string.count('1')

    # 打印转换过程(可选)
    print(f"十进制数 {decimal_num} 转换为二进制是: {binary_string[2:]}")
    
    return ones_count

# 示例
number = 13  # 二进制为 1101,有 3 个 1
count1 = count_ones_in_binary_builtin(number)
print(f"二进制中 1 的个数为: {count1}\n")

number = 25  # 二进制为 11001,有 3 个 1
count2 = count_ones_in_binary_builtin(number)
print(f"二进制中 1 的个数为: {count2}")
方法二:使用位运算 (Bitwise Operation) (最快且推荐)

这是计算机科学中常用的方法,尤其是 Brian Kernighan's Algorithm (布赖恩·科尼干算法)。它通过不断地进行 n = n & (n - 1) 操作来消除数字 n n n 最右边的 '1',直到 n n n 变为 0。循环的次数即为 '1' 的个数。

  • 位运算 (Bitwise Operation)
    • 解释 :直接对数字在内存中的二进制位进行操作的运算,比如"与"(AND, &)、"或"(OR, |)、"非"(NOT, ~)和"异或"(XOR, ^)。
    • 词源来历 :由 Bit (位,即二进制数字 0 或 1)和 Operation(操作)组成。
python 复制代码
def count_ones_in_binary_bitwise(decimal_num):
    """
    使用位运算(Brian Kernighan 算法)计算十进制数转换为二进制后 1 的个数。

    Args:
        decimal_num (int): 要转换的十进制非负整数。

    Returns:
        int: 二进制表示中 1 的个数。
    """
    if decimal_num < 0:
        return "输入必须是非负整数"
        
    count = 0
    n = decimal_num
    
    # 当 n 不为 0 时循环
    while n > 0:
        # n & (n - 1) 的作用是消除 n 最右边的一个 '1'
        n = n & (n - 1)
        count += 1
        
    return count

# 示例
number = 13  # 1101
count1 = count_ones_in_binary_bitwise(number)
print(f"使用位运算计算:十进制数 {number} 的二进制中 1 的个数为: {count1}\n")

number = 31  # 11111
count2 = count_ones_in_binary_bitwise(number)
print(f"使用位运算计算:十进制数 {number} 的二进制中 1 的个数为: {count2}")
方法三:传统除法取余法 (Modulo and Division) (最基础)

这是手动进行十进制转二进制运算的模拟:不断将数字除以 2 并取余数(即二进制位),直到商为 0。

  • 取模 (Modulo)
    • 解释:数学和计算机科学中的运算,计算一个数被另一个数除后的余数。
    • 词源来历 :英文 Modulo 源自拉丁语 modulus,意为"小测量,小尺度",常指代这种求余数的运算。
python 复制代码
def count_ones_in_binary_traditional(decimal_num):
    """
    使用传统的除法取余法计算十进制数转换为二进制后 1 的个数。

    Args:
        decimal_num (int): 要转换的十进制非负整数。

    Returns:
        int: 二进制表示中 1 的个数。
    """
    if decimal_num < 0:
        return "输入必须是非负整数"
        
    if decimal_num == 0:
        return 0
        
    count = 0
    n = decimal_num
    
    while n > 0:
        # 取余数:n % 2,如果余数是 1,则计数器加 1
        if n % 2 == 1:
            count += 1
            
        # 整数除法:n // 2,相当于向右移位
        n = n // 2
        
    return count

# 示例
number = 13
count1 = count_ones_in_binary_traditional(number)
print(f"使用传统方法计算:十进制数 {number} 的二进制中 1 的个数为: {count1}\n")

number = 10  # 1010
count2 = count_ones_in_binary_traditional(number)
print(f"使用传统方法计算:十进制数 {number} 的二进制中 1 的个数为: {count2}")

1. Python 内置函数 bin()count() 的记忆方法

函数 功能 记忆联想 (Memory Association)
bin() 将整数转换为以 '0b' 开头的二进制字符串。 Binary 的前三个字母。想到 Binarization(二值化),即转换为二进制。
count() 统计一个字符串或列表中特定元素的出现次数。 Count 就是"计数"的意思,非常好记。无论是在字符串(统计字符)还是列表(统计元素)中,它都用于统计数量。

记忆技巧:结合应用场景

将这两个函数放在一起记忆,因为它们在"数 1 1 1 的个数"这个场景下是完美组合:

  1. 第一步(转换) :我需要把数字变成二进制,所以用 bin()
  2. 第二步(计数) :我需要数里面的 1 1 1,所以用字符串的 count('1') 方法。

Python 内置函数 (Built-in Functions)

  • 解释:Python 语言自带的、可以直接使用的函数,无需导入任何模块。
  • 如何记忆 :Python 的内置函数数量有限且常用,建议通过多查文档、多写代码 的方式逐步熟悉。常见的如 print()len()type()input()int() 等,都是必掌握的。当您遇到一个需求时,先思考"Python 有没有内置的功能可以实现?",这会促使您去查找和记忆。

2. print(f"...") 的详细含义、与 return 的区别以及常见语法

A. print(f"十进制数 {decimal_num} 转换为二进制是: {binary_string[2:]}")
部分 含义 解释
print() 函数名 作用是将内容输出到标准输出设备(通常是控制台/屏幕)。
f"..." F-String 叫做 Formatted String Literal(格式化字符串字面量),是 Python 3.6 引入的简洁字符串格式化方法。
{} 占位符 在 F-String 中,花括号 {} 内可以直接放入 Python 表达式变量 ,程序运行时会用它们的值替换 {}
decimal_num 变量 打印变量 decimal_num 的值。
binary_string[2:] 切片 (Slice) 对字符串 binary_string 进行切片操作。bin() 函数的结果是 '0b1101'[2:] 的意思是从索引 2 开始取到字符串末尾 ,目的是去掉前缀 '0b',只保留纯二进制字符串。
B. printreturn 的根本区别
特性 print() return
作用 输出:将数据显示给用户(在控制台/屏幕上)。 返回 :将一个值从函数内部传递给函数被调用的地方(调用者)。
中断 不会中断函数的执行。 会立即中断函数的执行,并将结果带回。
必须性 可选。函数可以没有 print 可选。如果函数不需要返回值,可以省略 return,此时函数默认返回 None

记忆方法

  • Print :像按下了打印机,把内容在屏幕上。
  • Return :像一个快递员,带着结果返回到您调用它的地方。
C. 常见 print 语法(字符串格式化)
方法 语法 优势/特点
F-String (推荐) print(f"Name: {name}, Age: {age}") 最简洁、可读性高,直接在字符串内嵌入表达式。
.format() print("Name: {}, Age: {}".format(name, age)) 兼容性好(Python 2.7+),将值按顺序或通过关键字/索引代入。
% 占位符 (旧) print("Name: %s, Age: %d" % (name, age)) 类似 C 语言,但不够灵活,不推荐在新代码中使用。
D. "".join() 的用法

这是字符串操作中一个非常常用且高效 的用法,通常用于将列表(List) 元组(Tuple)中的字符串元素连接成一个单一的字符串。

  • 语法分隔符字符串.join(可迭代对象)
  • 工作原理 :它用前面的分隔符字符串,将可迭代对象(如列表)中的所有元素连接起来。
示例 结果 解释
", ".join(["A", "B", "C"]) "A, B, C" 使用逗号和空格 ", " 连接。
"".join(["h", "e", "l", "l", "o"]) "hello" 使用空字符串 "" 连接,即紧密拼接。

记忆方法 :把 "".join() 想象成一条拉链"" 是拉链把手,它负责将拉链两边的元素(列表中的字符串)连接 (join) 起来。


3. 位运算、入门与学习建议

A. 位运算 (Bitwise Operation)
  • 解释 :位运算是直接对数字在计算机内部的二进制位Bit ,即 0 0 0 或 1 1 1)进行操作的运算。它比普通的加减乘除运算更快,因为它是硬件级别的操作。
  • 常用 :在需要极致性能(如嵌入式开发、图形学)、加密算法、以及高效处理整数(如您遇到的数 1 1 1 的个数)时,位运算非常常用且高效。
运算符 英文名称 符号 作用
按位与 AND & 两位都为 1 1 1 时结果为 1 1 1,否则为 0 0 0。
按位或 OR ` `
按位异或 XOR ^ 两位不同时结果为 1 1 1,相同时为 0 0 0。
左移 Left Shift << 向左移动 N N N 位,相当于乘以 2 N 2^N 2N。
右移 Right Shift >> 向右移动 N N N 位,相当于整数除以 2 N 2^N 2N。
B. ifforwhile 的区分与记忆

它们都是控制流 (Control Flow) 语句,用于控制程序执行的顺序。

语句 英文名称/词源 作用 核心记忆点
if Condition(条件) 决策:根据一个或多个条件是否成立,执行相应的代码块。 "如果" (If) :判断是否执行。
for Iterate(迭代) 遍历 :针对一个已知的序列(如列表、字符串、固定次数的范围),依次处理序列中的每一个元素。 "针对每个" (For Each)次数已知,用于遍历。
while Loop(循环) 循环 :只要给定的条件持续为真,就重复执行代码块,直到条件不满足。 "当...时" (While)次数未知,依赖条件变化终止。
场景 您应该用哪个?
判断用户输入是否有效。 if (判断条件)
打印列表中的所有学生姓名。 for (遍历列表)
计算 N N N 转换为 0 0 0 之前被除以 2 2 2 的次数。 while (次数不固定,依赖 N > 0 N>0 N>0 这个条件)
对一个数组进行 10 10 10 次操作。 for (次数已知,range(10))

在 OJ/ACM 比赛中,程序的输入和输出通常需要完全符合题目要求,核心区别在于:

  1. 输入不是交互式的 :程序通常需要持续读取多行或多组输入 ,直到输入结束(EOF, End Of File)。
  2. 输出必须是纯净的 :不能有任何额外的提示性文字(比如 请输入...十进制数 ... 转换为...)。最终的输出结果必须是精确唯一的

ACM/OJ 格式下的实现

1. 核心函数(保持不变)

函数本身是正确的,只是需要去掉打印语句。

python 复制代码
def solve_count_ones(n):
    """
    核心计算逻辑:使用内置函数计算二进制中 1 的个数。
    (在 OJ 环境下,我们通常假设输入是符合预期的非负整数)
    """
    # 使用 bin() 转换为二进制字符串,然后用 count('1') 计数
    return bin(n).count('1')
2. 标准 ACM/OJ 主程序结构

由于 OJ 系统通常通过 EOF (End Of File) 来判断输入是否结束,Python 中最常见的处理方式是使用 sys.stdin.read().split() 或在 try-except 结构中使用 input()sys.stdin

方法一:适用于多行输入 (推荐)

使用 sys 模块,一次性读取所有输入并处理:

python 复制代码
import sys

def solve_count_ones(n):
    """核心计算逻辑"""
    # 避免负数检查和额外的打印语句,只返回结果
    # 如果题目有明确的输入范围限制,这里可以省略 try-except
    return bin(n).count('1')

def main_acm():
    # 读入所有输入数据,并按空格或换行符分割成列表
    # 列表中的每个元素都是一个字符串格式的数字
    input_data = sys.stdin.read().split()
    
    # 遍历列表中的每一个数据
    for data_str in input_data:
        # 排除空字符串(如果输入有额外的空行)
        if not data_str:
            continue
            
        try:
            # 将字符串转换为整数
            n = int(data_str)
            
            # 调用核心函数计算结果
            result = solve_count_ones(n)
            
            # 【关键】直接打印结果,不带任何额外文字
            print(result)
            
        except ValueError:
            # 如果遇到非数字输入,通常在 OJ 环境下可以忽略或根据题目要求处理
            continue

# 运行时调用主函数
# main_acm() 

方法二:使用 while True 循环读取每行输入

这种方法适用于题目明确规定每次只输入一个数字并换行的情况。

python 复制代码
# 方法二的实现,适用于每行一个测试用例
def main_acm_per_line():
    while True:
        try:
            # 尝试读取一行输入
            line = input()
            
            # 如果输入为空或结束,则退出循环
            if not line:
                break
                
            n = int(line)
            
            # 核心计算:bin(n).count('1')
            result = bin(n).count('1')
            
            # 【关键】纯净输出
            print(result)
            
        except EOFError:
            # 捕获 EOF (End Of File),表示输入已全部读取完毕
            break
        except ValueError:
            # 捕获输入转换错误,通常也选择退出或跳过
            break

# main_acm_per_line()

总结关键区别

特性 交互式/日常函数 ACM/OJ 格式
输入方式 input("请输入数字:") 使用 sys.stdin.read()while True: input() 循环读取。
输入次数 通常一次 持续读取多组测试用例,直到文件末尾 (EOF)。
输出 包含提示信息、中间步骤(如 print(f"十进制数..."))。 纯净,只输出最终的结果数字。
错误处理 需要友好地提示用户错误(如 return "输入必须是非负整数")。 简化错误处理,假设输入格式正确,或在 try-except 中静默退出。
相关推荐
炘东5925 小时前
让Pycharm的Terminal(终端)进入创建好的虚拟环境
ide·python·pycharm
花开花富贵5 小时前
表白❤不够格,草莓熊来帮忙!
python
我爱鸢尾花5 小时前
CNN基础理论讲解及Python代码复现
人工智能·python·深度学习·神经网络·算法·机器学习·cnn
love530love6 小时前
【笔记】解决 ComfyUI 安装节点 ComfyUI-Addoor (葵花宝典)后启动报错:No module named ‘ComfyUI-Addoor’
linux·运维·前端·人工智能·windows·笔记·python
love530love6 小时前
【笔记】ComfyUI KeyError: ‘tensorrt‘ 错误的完整解决方案
windows·笔记·python·pycharm
zzywxc7876 小时前
解锁 Rust 开发新可能:从系统内核到 Web 前端的全栈革命
开发语言·前端·python·单片机·嵌入式硬件·rust·scikit-learn
Rattenking6 小时前
【CSS】---- 图形函数详解
笔记·学习·flutter
极客数模6 小时前
2025年MathorCup 大数据竞赛明日开赛,注意事项!论文提交规范、模板、承诺书正确使用!2025年第六届MathorCup数学应用挑战赛——大数据竞赛
大数据·python·算法·matlab·图论·比赛推荐
.小小陈.6 小时前
数据结构3:复杂度
c语言·开发语言·数据结构·笔记·学习·算法·visual studio