每日一题——Python实现PAT乙级1019 数字黑洞(举一反三+思想解读+逐步优化)

news2024/9/21 4:28:20


一个认为一切根源都是“自己不够强”的INTJ

个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数

Python-3.12.0文档解读

目录

我的写法

点评代码的优缺点:

时间复杂度:

空间复杂度:

改进点:

我要更强

哲学和编程思想

举一反三


 

我的写法

import sys  # 导入sys模块,以便使用sys.exit()函数来退出程序

N=input()  # 从标准输入获取一个字符串
N=[int(i) for i in N.zfill(4)]  # 将输入的字符串填充至少4位,不足的部分用0填充,然后将每个字符转换为整数并存入列表N

l=int("".join(map(str,sorted(N,reverse=True))))  # 将列表N从大到小排序,转换成字符串然后转换成整数,赋值给l
r=int("".join(map(str,sorted(N))))  # 将列表N从小到大排序,转换成字符串然后转换成整数,赋值给r

if l==r:  # 如果l和r相等,表示所有位数都相同
    print(f"{l} - {l} = 0000")  # 输出结果,并且结果为0000
    sys.exit(0)  # 退出程序

while (l-r)!=6174:  # 当l和r的差不等于6174时,进入循环
    new=l-r  # 计算l和r的差,赋值给new
    print("%04d - %04d = %04d" % (l,r,new))  # 格式化输出l、r和他们的差
    new=[int(i) for i in str(new).zfill(4)]  # 将new填充至至少4位,转换成字符串,每个字符转换为整数并存入列表new
    l=int("".join(map(str,sorted(new,reverse=True))))  # 将new列表从大到小排序,转换成字符串然后转换成整数,赋值给l
    r=int("".join(map(str,sorted(new))))  # 将new列表从小到大排序,转换成字符串然后转换成整数,赋值给r

else:  # 当while循环退出时(当l-r等于6174)
    new=l-r  # 计算最后一次的l和r的差
    print("%04d - %04d = %04d" % (l,r,new))  # 格式化输出最后一次的l、r和他们的差

这段代码是为了解决卡普雷卡尔常数(Kaprekar's constant)问题,即通过不断对一个四位数进行排序和相减,来演示如何最终达到6174这个固定值(对于至少包含两个不同数字的四位数)。

点评代码的优缺点:

优点:

  1. 代码逻辑清晰,步骤分明,易于阅读和理解。
  2. 代码处理了输入数字不足四位的情况,通过使用zfill(4)来确保运算始终在四位数上进行。
  3. 格式化输出结果,易于用户查看每步的计算过程。

缺点:

  1. 缺乏输入验证,没有检查用户输入是否为合法的四位数字。
  2. 使用了sys.exit()来退出循环,这在某些情况下可能不是最好的实践。一般而言,应该避免在循环中使用退出函数,因为它会导致整个程序的退出,而不是仅仅跳出循环。可以考虑将循环放在一个函数中,并通过return来退出函数。
  3. 在每次循环中都进行了字符串和整数之间的相互转换,这增加了不必要的计算量和复杂性。

时间复杂度:

代码中的while循环最多会执行多少次不是固定的,它取决于初始数字到达6174需要的迭代次数。但对于任何至少包含两个不同数字的四位数,这个过程最多会迭代7次。因此,可以认为时间复杂度是O(1),即常数时间复杂度,与输入大小无关。

空间复杂度:

空间复杂度也是O(1),因为不管输入如何,代码中使用的变量数量保持不变,不会随着输入的增加而增加。

改进点:

对于该代码,可以考虑以下改进:

  • 添加对输入的验证,确保它是一个四位数,并且至少包含两个不同的数字。
  • 将重复的排序和转换操作封装为函数,减少代码的重复性并提高可读性。

考虑用更优雅的方式替代sys.exit()退出循环。


我要更强

为了优化时间复杂度和空间复杂度,我们可以考虑以下几点:

  1. 避免不必要的字符串和整数之间的转换。
  2. 使用更高效的数据结构和算法。
  3. 减少重复计算,例如,可以只对新产生的数字进行排序和转换,而不是每次都重新排序和转换。

下面是一个优化后的代码示例:

def kaprekar_process(num):
    # 确保输入是一个四位数
    if not (1000 <= num <= 9999) or len(set(str(num))) == 1:
        return "输入必须是一个至少包含两个不同数字的四位数"

    # 定义一个函数来计算Kaprekar过程的下一步
    def next_step(n):
        # 将数字转换为列表,方便排序
        digits = sorted([int(d) for d in str(n)])
        # 生成最大和最小可能的数字
        l = int(''.join(map(str, digits[::-1])))
        r = int(''.join(map(str, digits)))
        return l - r

    # 执行Kaprekar过程,直到结果为6174
    steps = 0
    while num != 6174:
        num = next_step(num)
        # 格式化输出
        print(f"{l:04d} - {r:04d} = {num:04d}")
        steps += 1

    return steps

# 测试代码
num = int(input("请输入一个四位数:"))
steps = kaprekar_process(num)
print(f"完成Kaprekar过程,共执行了{steps}步。")

在这个优化后的代码中,我们定义了一个内部函数next_step来计算Kaprekar过程的下一步,这样可以避免重复的代码。我们还添加了输入验证,确保输入是一个有效的四位数。此外,我们只对新产生的数字进行排序和转换,而不是每次都重新排序和转换,这样可以减少计算量。

时间复杂度:

由于我们只对新产生的数字进行排序和转换,时间复杂度仍然是O(1),因为对于任何有效的四位数,Kaprekar过程最多执行7次。

空间复杂度:

空间复杂度也是O(1),因为我们使用的变量数量是固定的,不会随着输入的增加而增加。

这个代码示例已经尽可能地优化了时间复杂度和空间复杂度,同时保持了代码的可读性和可维护性。


哲学和编程思想

优化这段代码涉及到的哲学和编程思想主要包括:

  1. 抽象化(Abstraction): 通过定义内部函数next_step,我们将计算Kaprekar过程的下一步的逻辑抽象出来,使得主函数更加简洁,易于理解和维护。这种抽象化的思想是编程中的一个基本原则,它允许我们将复杂的系统分解为更小、更易于管理的部分。

  2. 模块化(Modularity): 将功能分解为独立的模块或函数,每个模块负责一个特定的任务。这不仅提高了代码的可读性,还使得代码更容易测试和重用。在这个例子中,next_step函数就是一个模块,它负责计算Kaprekar过程的下一步。

  3. 优化(Optimization): 在编程中,优化通常指的是通过改进算法或数据结构来提高程序的性能。在这个例子中,我们避免了不必要的字符串和整数之间的转换,减少了计算量,从而优化了时间复杂度。

  4. DRY原则(Don't Repeat Yourself): 这个原则鼓励开发者避免代码重复。通过将重复的逻辑封装在next_step函数中,我们遵循了DRY原则,使得代码更加简洁和可维护。

  5. 输入验证(Input Validation): 在处理用户输入时,确保输入的有效性是至关重要的。这不仅有助于防止错误,还可以提高程序的健壮性。在这个例子中,我们添加了输入验证,确保输入是一个有效的四位数。

  6. 迭代(Iteration): 迭代是编程中的一个基本概念,它允许我们重复执行一组操作,直到满足某个条件。在这个例子中,我们使用了一个while循环来迭代执行Kaprekar过程,直到结果为6174。

  7. 格式化输出(Formatted Output): 格式化输出是一种编程实践,它使得输出更加清晰和易于理解。在这个例子中,我们使用了格式化字符串来确保输出始终是四位数,并且易于阅读。

这些哲学和编程思想是软件开发中的核心原则,它们有助于提高代码的质量、可维护性和性能。通过应用这些原则,可以创建出更加健壮、高效和易于理解的程序。


举一反三

以下是一些基于前面提到的哲学和编程思想的技巧,可以帮助在不同的编程场景中应用这些原则:

  1. 追求干净、可读的代码(DRY原则):

    • 标识重复的代码块并将它们抽象成函数或方法。
    • 使用循环和递归来处理重复的逻辑,而不是手动拷贝和粘贴代码。
    • 创建通用的代码模块,用于执行频繁使用的任务。
  2. 优化性能:

    • 分析代码,找出瓶颈,例如使用性能分析工具。
    • 选择合适的数据结构和算法来解决问题,例如使用哈希表来快速查找数据,而不是列表。
    • 避免在循环内部进行不必要的计算,将可以在循环外计算的表达式提出来。
  3. 简化复杂性(Abstraction):

    • 封装复杂的操作,提供简单的接口。
    • 避免过度工程,从最简单的解决方案开始,然后根据需要迭代和改进。
    • 使用设计模式来处理常见的设计问题。
  4. 提高代码的模块化(Modularity):

    • 设计独立的模块,每个模块执行一个单一的任务。
    • 使用接口或抽象类来定义模块之间的互动。
    • 尽量减少模块之间的依赖关系。
  5. 输入验证(Input Validation):

    • 总是检查外部输入,不要假定它们是有效的。
    • 使用异常处理来管理预期外的情况。
    • 对用户输入执行合理性检查,如数据类型、格式和范围。
  6. 迭代(Iteration):

    • 采用迭代的方法来逐步改进程序。
    • 使用版本控制系统来管理代码的变化,这样你可以安全地探索不同的解决方案。
    • 测试你的代码在每一次改进后的表现。
  7. 格式化输出(Formatted Output):

    • 使用字符串格式化来创建清晰、可读的输出。
    • 确保输出数据的格式符合用户的期望和行业标准。
    • 为输出的数据提供合适的上下文,使其对用户有意义。

这些技巧不仅限于特定的语言或框架;它们是普遍适用的编程实践,可以帮助编写更优质的代码。在实际应用中,应该根据具体的情况和需求灵活运用它们。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1808584.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构:插入排序和希尔排序

插入排序 逆序的情况下&#xff1a; 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) 顺序的情况下&#xff1a; 时间复杂度&#xff1a;O(N) 空间复杂度…

【Linux系统化学习】传输层——TCP协议

目录 预备知识 全双工协议 协议缓冲区 TCP协议 TCP协议格式 六个标志位 两个问题 确认应答机制 流量控制 超时重传机制 连接管理机制 CLOSE_WAIT状态 TIME_WAIT状态 滑动窗口 拥塞控制 延迟应答 捎带应答 粘包问题 TCP的异常情况 TCP小结 TCP/UDP协议对比…

首届IEEE RAS峰会,为什么大厂阿里、字节、腾讯都参加了?

"RAS in Data Centers 2024" 首届IEEE RAS&#xff08;Reliability, Availability, and Serviceability&#xff0c;即可靠性、可用性和可维护性&#xff09;在数据中心峰会在2024年6月11日至12日举行&#xff0c;地点设在美国加利福尼亚州圣克拉拉市的圣克拉拉万豪酒…

LangChain开发【NL2SQL】应用(few-shot优化)

前言 之前发布的博客LangGraph开发Agent智能体应用【NL2SQL】-CSDN博客&#xff0c;留了一个问题&#xff0c;对于相对复杂的sql&#xff08;leetcode中等难度的sql题&#xff09;&#xff0c;gpt4o就力不从心了。这篇文章来讲一下优化 什么是few-shot 使用这些少量的、调整…

公安视频图像信息数据库及GA/T 1400视图库视频监控系统的使用场景

随着科技的快速发展&#xff0c;大数据、人工智能等新技术不断融入各行各业&#xff0c;为各行各业带来了前所未有的变革。在公安领域&#xff0c;GA/T 1400协议公安视频图像信息数据库的应用为视频监控场景提供了强有力的支持&#xff0c;极大地提升了公安工作的效率和准确性。…

排序-快排算法对数组进行排序

目录 一、问题描述 二、解题思路 1.初始化 2.将右侧小于基准元素移到左边 3.将左侧大于基准元素移到右边 4.重复执行上面的操作 5.对分好的左、右分区再次执行分区操作 6.最终排序结果 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 快排算法实现数组排序&am…

算法金 | A - Z,115 个数据科学 机器学习 江湖黑话(全面)

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 机器学习本质上和数据科学一样都是依赖概率统计&#xff0c;今天整整那些听起来让人头大的机器学习江湖黑话 A - C A/B Testing (A/B …

保姆级讲解 Linux下FTP服务器的搭建、配置与管理

本来目录很长的 因为感觉不太美观 所以小标题都删掉了 本文介绍了 本地用户的FTP服务器搭建实例匿名用户的FTP服务器搭建实例虚拟用户的FTP服务器搭建实例企业常见类型搭建实验 配置与管理FTP服务器 配置与管理FTP服务器一、FTP相关知识二、项目设计与准备三、项目实施四、认识…

存内计算与扩散模型:下一代视觉AIGC能力提升的关键

目录 前言 视觉AIGC的ChatGPT4.0时代 扩散模型的算力“饥渴症” 存内计算解救算力“饥渴症” 结语 前言 ​ 在这个AI技术日新月异的时代&#xff0c;我们正见证着前所未有的创新与变革。尤其是在视觉内容生成领域&#xff08;AIGC&#xff0c;Artificial Intelligence Generate…

python导入非当前目录(如:父目录)下的内容

在开发python项目时&#xff0c;通常会划分不同的目录&#xff0c;甚至不同层级的目录&#xff0c;这时如果直接导入不在当前目录下的内容时&#xff0c;会报如下的错误&#xff1a;ModuleNotFoundError: No module named miniai其实这里跟操作系统的环境变量很类似的&#xff…

less学习笔记

一、什么是less&#xff1f; Less是CSS预处理语言&#xff0c;可以使用变量、嵌套、运算等&#xff0c;便于维护项目CSS样式代码。 二、less安装 使用npm包管理工具&#xff0c;全局安装less包 npm install -g lessless安装好的同时&#xff0c;lessc也安装好了 通过 lessc -…

【图解IO与Netty系列】Netty核心组件解析

Netty核心组件解析 Bootstrap & ServerBootstrapEventLoop & EventLoopGroupChannelChannelHandler & ChannelPipeline & ChannelHandlerContextChannelHandlerChannelPipelineChannelHandlerContext ChannelFuture Bootstrap & ServerBootstrap Bootstra…

代码随想录算法训练营第36期DAY56

DAY56 套磁很顺利&#xff0c;发现又有书读了&#xff01; 300最长递增子序列 朴素法&#xff0c;这个好想&#xff0c;但是不对&#xff0c;比如 0 1 0 3 2 3 我的算法会找出0 1 3作为答案&#xff0c;而不是0 1 2 3 可以看出&#xff0c;后面的状态依赖于前面的状态&am…

ELK组件

资源列表 操作系统 IP 主机名 Centos7 192.168.10.51 node1 Centos7 192.168.10.52 node2 部署ELK日志分析系统 时间同步 chronyc sources -v 添加hosts解析 cat >> /etc/hosts << EOF 192.168.10.51 node1 192.168.10.52 node2 EOF 部署Elasticsea…

Oracle10.2.0.1冷备迁移之_数据文件拷贝方式

由于阿里云机房要下架旧服务器&#xff0c;单位未购买整机迁移服务&#xff0c;且业务较老不兼容Oracle11g&#xff0c;所以新购买一台新服务器进行安装Oracle10.2.0.1 &#xff0c;后续再将数据迁移到新服务器上。 id 数据库版本 操作系统版本 实例名 源库 115.28.242.25…

[数据集][目标检测]厨房积水检测数据集VOC+YOLO格式88张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;88 标注数量(xml文件个数)&#xff1a;88 标注数量(txt文件个数)&#xff1a;88 标注类别数…

tcp协议的延迟应答(介绍+原则),拥塞控制(拥塞窗口,网络出现拥塞时,滑动窗口的大小如何确定,慢启动,阈值)

目录 延迟应答 引入 介绍 原则 拥塞控制 引入 网络出现拥塞 引入 介绍 介绍 拥塞窗口 介绍 决定滑动窗口的大小 慢启动 介绍 为什么要有慢启动 阈值 算法 总结 延迟应答 引入 发送方一次发送更多的数据,发送效率就越高 因为要写入网卡硬件的io速度很慢,尽量…

Chroium 源码目录结构分析(1):源码目录体积一栏

获取源码 首先&#xff0c;我们拉一份最新的源代码&#xff08;笔者是2024.6.6日拉取的&#xff09;&#xff1a; fetch --nohistory chromium 源码预处理 如果运行build&#xff0c;会生成许多生成的代码&#xff0c;因此我们不运行build。 然后&#xff0c;把干扰后续分析…

Python Requests库详解

大家好&#xff0c;在现代网络开发中&#xff0c;与Web服务器进行通信是一项至关重要的任务。Python作为一种多才多艺的编程语言&#xff0c;提供了各种工具和库来简化这一过程。其中&#xff0c;Requests库作为Python中最受欢迎的HTTP库之一&#xff0c;为开发人员提供了简单而…

python实践笔记(一): 模块和包

1. 写在前面 最近在重构之前的后端代码&#xff0c;借着这个机会又重新补充了关于python的一些知识&#xff0c; 学习到了一些高效编写代码的方法和心得&#xff0c;比如构建大项目来讲&#xff0c;要明确捕捉异常机制的重要性&#xff0c; 学会使用try...except..finally&…