当前位置: 首页 > news >正文

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

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


Python 实现

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

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

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

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) 操作来消除数字 nnn 最右边的 ‘1’,直到 nnn 变为 0。循环的次数即为 ‘1’ 的个数。

  • 位运算 (Bitwise Operation)
    • 解释:直接对数字在内存中的二进制位进行操作的运算,比如“与”(AND, &)、“或”(OR, |)、“非”(NOT, ~)和“异或”(XOR, ^)。
    • 词源来历:由 Bit(位,即二进制数字 0 或 1)和 Operation(操作)组成。
def count_ones_in_binary_bitwise(decimal_num):"""使用位运算(Brian Kernighan 算法)计算十进制数转换为二进制后 1 的个数。Args:decimal_num (int): 要转换的十进制非负整数。Returns:int: 二进制表示中 1 的个数。"""if decimal_num < 0:return "输入必须是非负整数"count = 0n = decimal_num# 当 n 不为 0 时循环while n > 0:# n & (n - 1) 的作用是消除 n 最右边的一个 '1'n = n & (n - 1)count += 1return 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,意为“小测量,小尺度”,常指代这种求余数的运算。
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 0count = 0n = decimal_numwhile n > 0:# 取余数:n % 2,如果余数是 1,则计数器加 1if n % 2 == 1:count += 1# 整数除法:n // 2,相当于向右移位n = n // 2return 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 就是“计数”的意思,非常好记。无论是在字符串(统计字符)还是列表(统计元素)中,它都用于统计数量。

记忆技巧:结合应用场景

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

  1. 第一步(转换):我需要把数字变成二进制,所以用 bin()
  2. 第二步(计数):我需要数里面的 111,所以用字符串的 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,即 000111)进行操作的运算。它比普通的加减乘除运算更快,因为它是硬件级别的操作。
  • 常用:在需要极致性能(如嵌入式开发、图形学)、加密算法、以及高效处理整数(如您遇到的111 的个数)时,位运算非常常用且高效。
运算符英文名称符号作用
按位与AND&两位都为 111 时结果为 111,否则为 000
按位或OR``
按位异或XOR^两位不同时结果为 111,相同时为 000
左移Left Shift<<向左移动 NNN 位,相当于乘以 2N2^N2N
右移Right Shift>>向右移动 NNN 位,相当于整数除以 2N2^N2N
B. ifforwhile 的区分与记忆

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

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

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

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

ACM/OJ 格式下的实现

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

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

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 模块,一次性读取所有输入并处理:

import sysdef solve_count_ones(n):"""核心计算逻辑"""# 避免负数检查和额外的打印语句,只返回结果# 如果题目有明确的输入范围限制,这里可以省略 try-exceptreturn bin(n).count('1')def main_acm():# 读入所有输入数据,并按空格或换行符分割成列表# 列表中的每个元素都是一个字符串格式的数字input_data = sys.stdin.read().split()# 遍历列表中的每一个数据for data_str in input_data:# 排除空字符串(如果输入有额外的空行)if not data_str:continuetry:# 将字符串转换为整数n = int(data_str)# 调用核心函数计算结果result = solve_count_ones(n)# 【关键】直接打印结果,不带任何额外文字print(result)except ValueError:# 如果遇到非数字输入,通常在 OJ 环境下可以忽略或根据题目要求处理continue# 运行时调用主函数
# main_acm() 

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

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

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

总结关键区别

特性交互式/日常函数ACM/OJ 格式
输入方式input("请输入数字:")使用 sys.stdin.read()while True: input() 循环读取。
输入次数通常一次持续读取多组测试用例,直到文件末尾 (EOF)。
输出包含提示信息、中间步骤(如 print(f"十进制数..."))。纯净,只输出最终的结果数字。
错误处理需要友好地提示用户错误(如 return "输入必须是非负整数")。简化错误处理,假设输入格式正确,或在 try-except 中静默退出。
http://www.dtcms.com/a/519769.html

相关文章:

  • 长春怎么注册网站平台wordpress 视频列表
  • 【ReAcTable】面向表格问答任务的ReAct增强框架
  • Docker 部署 Elasticsearch 全流程手册
  • React 集成Redux数据状态管理 数据共享 全局共享
  • Docker与Nginx:现代Web部署的完美二重奏
  • 【JUnit实战3_08】第四章:从 JUnit 4 迁移到 JUnit 5
  • React 03
  • 前端基础之《React(2)—webpack简介-使用Babel》
  • 广州网站建设公司嘉御建设手机银行网站
  • 【Linux系统编程】软件包管理器
  • 怎么快速定位bug?如何编写测试用例?
  • NetIP,一款开源的快速网络信息查看工具
  • 有限元方法核心原理与学习路径:从一维基础到多维拓展(七步流程)
  • TCP(滑动窗口/拥塞窗口补充)
  • nginx前端部署与Vite环境变量配置指南
  • webrtc getStats 内部调用流程分析
  • 通过 Stdio(标准输入/输出)传输机制,实现 CrewAI 与本地 MCP 服务器的连接
  • 英文版网站建设方案手机app免费制作
  • 通过API网关部署FC函数
  • 单例模式精写
  • SQL sever数据库--第三次作业
  • XLM-R模型:大规模跨语言表示的突破与实践
  • GitLab 多安全漏洞可致攻击者触发拒绝服务状态
  • JAVA基础篇:分支结构——让程序学会“做选择”
  • SpringDataRedis 快速入门总结
  • 安徽省建设厅网站资料下载建了qq群 如何快速推广
  • 重庆做木门网站公司龙城区建设局网站
  • 手机网站支持微信支付做网站需要什么资料
  • P4766 [CERC2014] Outer space invaders 题解
  • CS5005:400mA,低噪声,电荷泵DC/DC转换电路