每日一题——Python实现PAT乙级1028 人口普查 Keyboard(举一反三+思想解读+逐步优化)六千字好文

news2025/2/24 12:05:00


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

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

Python-3.12.0文档解读

目录

题目链接​编辑我的写法

专业点评

时间复杂度分析

空间复杂度分析

总结

我要更强

优化代码

优化解释

进一步优化

总结

哲学和编程思想

1. KISS (Keep It Simple, Stupid)

2. DRY (Don't Repeat Yourself)

3. YAGNI (You Aren't Gonna Need It)

4. Separation of Concerns

5. Single Responsibility Principle (SRP)

6. Efficient Input/Output Handling

7. Algorithmic Efficiency

8. Minimal State

9. Readability and Maintainability

10. Resource Management

举一反三

1. KISS (Keep It Simple, Stupid)

2. DRY (Don't Repeat Yourself)

3. YAGNI (You Aren't Gonna Need It)

4. Separation of Concerns

5. Single Responsibility Principle (SRP)

6. Efficient Input/Output Handling

7. Algorithmic Efficiency

8. Minimal State

9. Readability and Maintainability

10. Resource Management

举一反三的具体技巧


题目链接我的写法

# 输入一个整数N,表示接下来有N个人的名字和生日需要输入
N = int(input())

# 初始化合理的生日数量
resonable_birthdays_num = 0

# 初始化最年轻人的名字
youngest_name = ''

# 初始化最年轻人的生日为一个非常早的日期
youngest_birthday = 18140905

# 初始化最年长人的名字
oldest_name = ''

# 初始化最年长人的生日为一个非常晚的日期
oldest_birthday = 20140907

# 使用循环从1运行到N次,用于输入每个人的名字和生日
for i in range(N):
    # 输入名字和生日,使用空格分隔
    name, birthday = input().split()
    
    # 将生日中的斜杠替换为空,并转换为整数格式
    birthday = int(birthday.replace('/', ''))
    
    # 检查生日是否在合理的范围内
    if 18140906 <= birthday <= 20140906:
        # 如果生日合理,合理生日数量加1
        resonable_birthdays_num += 1
        
        # 更新最年长人的数据,如果当前生日比最年长人的生日早
        if birthday < oldest_birthday:
            oldest_name = name
            oldest_birthday = birthday
        
        # 更新最年轻人的数据,如果当前生日比最年轻人的生日晚
        if youngest_birthday < birthday:
            youngest_name = name
            youngest_birthday = birthday

# 如果有合理的生日,输出合理的生日数量、最年长人的名字、最年轻人的名字
if resonable_birthdays_num:
    print(resonable_birthdays_num, oldest_name, youngest_name)
# 如果没有合理的生日,输出0
else:
    print('0')

这段代码是一个用于处理生日信息的小程序,通过输入多个名字和生日,找出其中最年长和最年轻的人。下面是对这段代码的专业点评以及时间复杂度和空间复杂度的分析。

专业点评

  1. 输入处理:
    • 数字N的输入和处理逻辑非常清晰。
    • 使用split()方法分割名字和生日,使用replace()方法处理生日格式再转换为整数,这是合理的。
  2. 初始化:
    • 变量的初始化清晰且符合逻辑,特别是对最年轻和最年长生日的初始值设置非常好。
  3. 逻辑判断:
    • 使用合理的范围(18140906到20140906)来判断生日是否在合理范围内,符合实际需求。
    • 更新最年长和最年轻人的逻辑分开处理,且条件明确。
  4. 输出结果:
  • 合理地检查了合理生日的数量,并根据不同情况输出相应的结果。

时间复杂度分析

时间复杂度是用来分析算法执行时间随输入规模增长的变化情况。

  1. 变量初始化:
    • 初始化变量O(1)。
  2. 输入处理和循环:
    • 循环N次处理输入,每次处理包含字符串分割、替换和转换操作,这些操作的时间复杂度为O(1)。
    • 因此,循环部分的总时间复杂度为O(N)。
  3. 更新逻辑:
    • 在每次循环中更新合理生日数量、最年长和最年轻人的逻辑都是常数时间操作O(1)。
  4. 输出结果:
  • 最后的输出操作也是常数时间O(1)。

综合上述分析,整个程序的时间复杂度为O(N)。

空间复杂度分析

空间复杂度是用来分析算法在运行过程中占用的内存空间。

  1. 变量初始化:
    • 初始化了多个变量,这些变量的空间复杂度为O(1)。
  2. 输入处理:
  • 每次处理一个输入,存储名字和生日的临时变量,且这些变量在每次循环结束后会被释放。
  • 由于我们不存储所有输入数据,只进行逐个处理,因此空间复杂度为O(1)。

综合上述分析,整个程序的空间复杂度为O(1)。

总结

这段代码逻辑清晰且结构合理,能够高效地处理输入数据并找出最年长和最年轻的人的名字。其时间复杂度和空间复杂度均为有效的O(N)和O(1),表现良好。可以考虑在输入数据量非常大的情况下进一步优化,例如通过更高效的输入处理方法或并行处理,但对于一般情况,这段代码已经非常健壮和高效。


我要更强

在这段代码中,时间复杂度已经是O(N),空间复杂度是O(1)。在这种情况下,进一步优化时间复杂度是不可行的,因为我们需要遍历所有输入以找到最年长和最年轻的人。不过,我们可以通过一些方式来提升代码的可读性和效率,比如:

  1. 使用更高效的输入方式来优化批量输入。
  2. 减少不必要的变量赋值来优化空间使用。

下面给出一些优化建议和相应的代码:

使用更高效的输入方式

在Python中,可以使用sys.stdin.read来一次性读取所有输入,然后逐行处理,这可能会提高大量输入情况下的速度。

合并部分逻辑

将最年长和最年轻人的检查逻辑合并到一次判断中。

优化代码

下面是优化后的代码:

import sys

# 从标准输入读取所有数据
input_data = sys.stdin.read().strip().split('\n')

# 第一个输入为整数N,表示接下来有N个人的名字和生日需要输入
N = int(input_data[0])

# 初始化合理的生日数量
resonable_birthdays_num = 0

# 初始化最年轻人的名字
youngest_name = ''

# 初始化最年轻人的生日为一个非常早的日期
youngest_birthday = 18140905

# 初始化最年长人的名字
oldest_name = ''

# 初始化最年长人的生日为一个非常晚的日期
oldest_birthday = 20140907

# 使用循环从1运行到N次,用于输入每个人的名字和生日
for i in range(1, N + 1):
    # 输入名字和生日,使用空格分隔
    name, birthday = input_data[i].split()
    
    # 将生日中的斜杠替换为空,并转换为整数格式
    birthday = int(birthday.replace('/', ''))
    
    # 检查生日是否在合理的范围内
    if 18140906 <= birthday <= 20140906:
        # 如果生日合理,合理生日数量加1
        resonable_birthdays_num += 1
        
        # 更新最年长或最年轻人的数据
        if birthday < oldest_birthday:
            oldest_name = name
            oldest_birthday = birthday
        if birthday > youngest_birthday:
            youngest_name = name
            youngest_birthday = birthday

# 如果有合理的生日,输出合理的生日数量、最年长人的名字、最年轻人的名字
if resonable_birthdays_num:
    print(resonable_birthdays_num, oldest_name, youngest_name)
# 如果没有合理的生日,输出0
else:
    print('0')

优化解释

  1. 输入优化:
    • 使用sys.stdin.read()一次性读取所有输入数据并分割为行,这在处理大量输入时比逐行调用input()更高效。
  2. 减少变量赋值:
  • 合并最年轻和最年长人的判断逻辑,减少重复的条件判断和变量赋值操作。

进一步优化

在目前这段代码的时间复杂度和空间复杂度都已经是较优的状态。时间复杂度是O(N),空间复杂度是O(1)。在这种情况下,进一步优化主要体现在代码可读性和执行效率的小提升上。

总结

对于这个问题,进一步的优化空间有限。主要优化方向在于提高输入效率和减少冗余的代码。上述代码已经尽可能地优化了时间复杂度和空间复杂度,同时保持了代码的可读性和易维护性。


哲学和编程思想

在优化和重构代码的过程中,我们运用了多种编程思想和软件设计哲学。这些思想和哲学帮助我们编写更高效、可维护且可读性更好的代码。以下是具体说明:

1. KISS (Keep It Simple, Stupid)

尽量保持代码简单明了。复杂的解决方案容易引发错误且难以维护。我们在优化代码时,通过减少不必要的变量赋值和合并逻辑判断,保持了代码的简单性。

  • 应用例子: 合并最年长和最年轻人判断的逻辑。
if birthday < oldest_birthday:
    oldest_name = name
    oldest_birthday = birthday
if birthday > youngest_birthday:
    youngest_name = name
    youngest_birthday = birthday

2. DRY (Don't Repeat Yourself)

避免代码重复,尽量使用统一的代码块来处理相似的任务。减少重复的代码不仅可以减少错误的发生,还能使代码更加简洁。

  • 应用例子: 合并生日范围判断后的逻辑处理。
if 18140906 <= birthday <= 20140906:
    resonable_birthdays_num += 1
    if birthday < oldest_birthday:
        oldest_name = name
        oldest_birthday = birthday
    if birthday > youngest_birthday:
        youngest_name = name
        youngest_birthday = birthday

3. YAGNI (You Aren't Gonna Need It)

只实现当前需要的功能,而不是预先考虑所有可能的功能需求。这样可以避免代码变得臃肿和复杂。

  • 应用例子: 只关注合理生日数量、最年长和最年轻人的逻辑处理,而没有引入额外不必要的功能。

4. Separation of Concerns

将不同的功能逻辑分离开来,使得每个部分只专注于其单一的功能,这样代码更容易理解和维护。

  • 应用例子: 输入处理和逻辑判断分开,清晰地分离了输入数据和业务逻辑。

5. Single Responsibility Principle (SRP)

每个模块或函数应该只有一个职责。这使得代码更加模块化,便于测试和维护。

  • 应用例子: 输入处理部分和结果输出部分分开,确保每段代码只处理一个功能。

6. Efficient Input/Output Handling

在处理大量数据时,使用高效的输入输出方法可以显著提升程序的性能。在Python中,使用sys.stdin.read()一次性读取所有输入数据而不是逐行读取是一种常见的优化方式。

  • 应用例子: 使用sys.stdin.read()来优化输入处理。
import sys
input_data = sys.stdin.read().strip().split('\n')

7. Algorithmic Efficiency

尽可能选择高效的算法和数据结构来解决问题,尽量减少时间和空间复杂度。

  • 应用例子: 使用O(N)复杂度的算法遍历输入数据,避免了多余的嵌套循环或不必要的复杂操作。

8. Minimal State

保持状态最小化,减少临时变量的使用和状态的改变,从而使代码更易于理解和调试。

  • 应用例子: 减少不必要的变量赋值,只保留必要的状态变量,如oldest_name和youngest_name。

9. Readability and Maintainability

编写易读的代码,使得代码在将来需要修改或扩展时更容易理解和维护。

  • 应用例子: 通过合理的变量命名和清晰的结构,使代码易于阅读和理解。

10. Resource Management

高效地管理资源,特别是在处理大量输入输出时,尽可能减少资源的浪费。

  • 应用例子: 使用sys.stdin.read一次性读取所有输入,减少多次I/O操作的开销。

通过运用这些编程思想和软件设计哲学,我们不仅优化了代码的时间和空间复杂度,还提高了代码的可维护性和可读性。这样不仅能确保当前需求得到高效的实现,还为将来的扩展和维护打下了良好的基础。


举一反三

以下是一些技巧和策略,帮助你在优化和重构代码时更好地应用这些编程思想和软件设计哲学:

1. KISS (Keep It Simple, Stupid)

  • 技巧: 从最直接、最简单的解决方案开始,如果简单的解决方案不能满足需求,再逐步增加复杂性。
  • 策略: 定期审查代码,问自己是否有更简单的方法来实现同样的功能。

2. DRY (Don't Repeat Yourself)

  • 技巧: 使用函数、类和模块来封装重复的代码段。
  • 策略: 进行代码审查时,特别留意重复的代码,尝试将其抽取成独立的函数或模块。

3. YAGNI (You Aren't Gonna Need It)

  • 技巧: 在实现功能时,严格限定在当前需求的范围内,不要过早优化或为可能的需求预留空间。
  • 策略: 在项目规划和代码评审时,确保每次只实现当前需求。

4. Separation of Concerns

  • 技巧: 将不同功能的代码分离到独立的模块或类中,使每个部分专注于单一职责。
  • 策略: 使用层次化设计,区分数据访问层、业务逻辑层和表现层。

5. Single Responsibility Principle (SRP)

  • 技巧: 每个函数或类只做一件事,并且名字能明确反映其职责。
  • 策略: 定期重构代码,确保每个模块或函数都符合单一职责原则。

6. Efficient Input/Output Handling

  • 技巧: 在处理大量数据时,尽量使用批量处理方法,减少I/O操作次数。
  • 策略: 优化数据流和缓冲区的使用,确保I/O操作的高效性。

7. Algorithmic Efficiency

  • 技巧: 选择合适的数据结构和算法,确保时间和空间复杂度最小化。
  • 策略: 在编写和优化代码时,使用复杂度分析工具和技术,确保高效实现。

8. Minimal State

  • 技巧: 只保留必要的状态,避免不必要的临时变量和状态变化。
  • 策略: 在代码编写和审查时,关注变量的生命周期和作用域,减少不必要的状态管理。

9. Readability and Maintainability

  • 技巧: 使用有意义的变量名、函数名和注释,提高代码的可读性。
  • 策略: 定期进行代码审查,确保代码清晰和易于理解。

10. Resource Management

  • 技巧: 使用上下文管理器和适当的资源释放机制,确保资源的高效利用。
  • 策略: 在处理文件、网络连接等资源时,使用with语句等上下文管理工具,确保资源得到正确管理。

举一反三的具体技巧

  1. 代码审查和重构: 定期进行代码审查,并将重构作为开发过程的一部分。识别并消除代码中的重复和复杂性。
  2. 学习和借鉴: 学习优秀开源项目代码,借鉴其设计模式和编程思想。分析和理解其背后的设计决策。
  3. 测试驱动开发(TDD): 使用TDD确保代码的可靠性和可维护性。编写测试用例可以帮助你更好地理解和分离代码的职责。
  4. 工具和自动化: 使用代码分析和格式化工具(如Pylint、Black等)保持代码风格一致性,自动化测试和部署流程。
  5. 文档和注释: 编写详尽的文档和注释,确保代码的可读性和可维护性。尤其是在代码复杂的地方,详细说明其逻辑和设计意图。

通过不断实践和反思这些技巧和策略,可以逐步提升代码质量,编写出高效、易维护且易读的代码。


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

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

相关文章

Windows 11 中安装 Docker Desktop 并安装镜像

本该主要介绍在 Windows 11 中安装 Docker Desktop 时的一些准备工作&#xff0c;以及该如何下载和安装&#xff0c;然后分别使用管理界面和 Docker 命令安装两个镜像。 一、准备工作 在 Windows 11 中安装 Docker Desktop 前&#xff0c;需要做一些准备。打开 【Windows 功能…

R语言数据分析案例28-对数据集可视化和T检验

一、分析主题&#xff1a; 本分析旨在对数据集进行可视化和 T 检验&#xff0c;以探索数据集中的变量之间的关系和差异。通过可视化数据&#xff0c;我们可以直观地了解数据的分布和趋势&#xff0c;而 T 检验则可以帮助我们确定这些差异是否具有统计学意义。 二、具体分析 …

【CS.AL】算法必学之贪心算法:从入门到进阶 —— 关键概念和代码示例

文章目录 1. 概述2. 适用场景3. 设计步骤4. 优缺点5. 典型应用6. 题目和代码示例6.1 简单题目&#xff1a;找零问题6.2 中等题目&#xff1a;区间调度问题6.3 困难题目&#xff1a;分数背包问题 7. 题目和思路表格8. 总结References 1000.1.CS.AL.1.4-核心-GreedyAlgorithm-Cre…

ATF是如何完成双系统切换的?

ATF&#xff08;Arm Trusted Firmware&#xff09;是一个用于ARM架构处理器的可信固件&#xff0c;它最初提供的最主要的功能就是&#xff1a;双系统切换和电源管理。 那么如何进行双系统切换呢&#xff0c;在双系统切换的示例中&#xff0c;除了CPU的跳转&#xff0c;例如CPU…

【面试干货】Java集合类详解:List、Set、Queue、Map、Stack的特点与用法

【面试干货】Java集合类详解&#xff1a;List、Set、Queue、Map、Stack的特点与用法 1、Map1.1 特点1.2 用法1.3 常见的实现类 2、Set2.1 特点2.2 用法2.3 常见的实现类 3、List3.1 特点3.2 用法3.3 常见的实现类 4、Queue4.1 特点4.2 用法4.3 常见的实现类 5、Stack5.1 特点5.…

瀑布流布局:图片浏览页面

目录 任务描述 相关知识 HTML(HyperText Markup Language) 瀑布流布局&#xff1a; 题目 任务描述 在本关中&#xff0c;你的任务是理解瀑布流布局&#xff0c;以展示多张图片。瀑布流布局使得图片能够按照设定的列数依次排列&#xff0c;每列的高度会根据图片的高度自动调…

【单片机毕业设计选题24007】-基于STM32和阿里云的家庭健康数据监测系统

系统功能: 本课题设计是基于STM32单片机作为控制主体&#xff0c;通过HX711称重模块&#xff0c;HC-SR04超声波测距模块&#xff0c;红外测温&#xff0c;心率传感器等模块通过I2C或SPI接口与STM32进行通信&#xff0c;并读取传感器输出的身高&#xff0c;体重&#xff0c;心率…

一年前 LLM AGI 碎片化思考与回顾系列④ · 从System2→Post-training的疑虑和思考

阅读提示&#xff1a; 本篇系列内容的是建立于自己过去一年在以LLM为代表的AIGC快速发展浪潮中结合学术界与产业界创新与进展的一些碎片化思考并记录最终沉淀完成&#xff0c;在内容上&#xff0c;与不久前刚刚完稿的那篇10万字文章 「融合RL与LLM思想&#xff0c;探寻世界模型…

B+索引的分裂及选择率和索引基数

1、B树索引的分裂 B树索引页的分裂并不总是从页的中间记录开始&#xff0c;这样可能会导致页空间的浪费。 例子 比如下面这个记录&#xff1a; 1、2、3、4、5、6、7、8、9 由于插入是以自增的顺序进行的&#xff0c;若这时插入第10条记录然后进行页的分裂操作&#xff0c;那…

QChar转换为Unicode,判断数字、字母、符号、标点

实现 QChar转换为Unicode&#xff0c;判断数字、字母、符号、标点等 #include "widget.h" #include "ui_widget.h" #include "QMessageBox"widget::widget(QWidget *parent): QWidget(parent), ui(new Ui::widget) {ui->setupUi(this); }widg…

Java 网站开发入门指南:如何用java写一个网站

Java 网站开发入门指南&#xff1a;如何用java写一个网站 Java 作为一门强大的编程语言&#xff0c;在网站开发领域也占据着重要地位。虽然现在 Python、JavaScript 等语言在网站开发中越来越流行&#xff0c;但 Java 凭借其稳定性、可扩展性和丰富的生态系统&#xff0c;仍然…

TF-IDF算法详细介绍

TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;是一种用于信息检索和文本挖掘的统计方法&#xff0c;旨在评估一个词在文档集合或语料库中的重要性。它是计算机科学和文本分析中最常用的特征提取技术之一。本文将详细介绍TF-IDF的基本概念、计算方法…

CentOS7.9 安装jdk17

切换到目录 /usr/local/src cd /usr/local/src下载压缩包 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz解压 tar -zxvf jdk-17_linux-x64_bin.tar.gz添加环境变量 vim /etc/profile重加载环境变量 export JAVA_HOME/usr/local/usr/jdk-1…

AI影像时代来临,联发科天玑以专业无畏精神重新定义手机专业影像

近期&#xff0c;联发科与Discovery探索频道联合举办了一场以“越极境&#xff0c;见芯境”为主题的天玑影像展&#xff0c;活动地点位于我国桂林阳朔。活动现场展示了阳朔壮美山水的画卷&#xff0c;以及救援队员在岩壁上进行训练的极限瞬间。令人意想不到的是&#xff0c;这些…

DockerHub无法访问,国内镜像拉取迂回解决方案

无法访问后&#xff0c;主要存在以下几个问题&#xff1a; 无法进行镜像的搜索无法查看镜像相关的使用说明无法直接拉取镜像 对于第二点&#xff0c;目前没啥解决思路&#xff0c;主要针对第一点和第三点。 解决无法搜索镜像 目前仅可以解决部分问题&#xff0c;在知道镜像名…

基于 Redis 实现分布式缓存

一、单节点 Redis 的问题 1.1 存在的问题 1、数据丢失问题&#xff1a;Redis 是内存存储&#xff0c;服务重启可能会丢失数据。 2、并发能力问题&#xff1a;单节点 Redis 并发能力虽然不错&#xff0c;但也无法满足如 618 这样的高并发场景。 3、故障恢复问题&#xff1a;如果…

小白跟做江科大32单片机之定时器

原理部分 1. 计数器每遇到一个上升沿就会计数值1,。 72MHZ72000000 72000000/65536/655360.0167638063430786132812559.652323555555554 (s) 2. 3. 计数时钟每来一个上升沿&#xff0c;计数值1&#xff0c;自动运行。如果计数值与存储在自动重装载寄存器中的值相等&#…

2024 年最新 Python 基于百度智能云实现短语音识别、语音合成详细教程

百度智能云语音识别 采用国际领先的流式端到端语音语言一体化建模算法&#xff0c;将语音快速准确识别为文字&#xff0c;支持手机应用语音交互、语音内容分析、机器人对话等场景。百度短语音识别可以将 60 秒以下的音频识别为文字。适用于语音对话、语音控制、语音输入等场景…

C++ 32 之 静态成员函数

#include <iostream> #include <string> using namespace std;// 特点: // 1.在编译阶段就分配了内存空间 // 2.类内声明&#xff0c;在类外进行初始化 // 3.所有对象共享一份静态成员数据 class Students02{ public:int s_c;static int s_d;// 静态成员函数&#…

重装了mysql,然后安装为服务时,net start 启动一直报错,MySQL服务无法启动的解决

之前写过一篇关于安装mysql的文章&#xff0c;按上面的处理&#xff0c;基本上是可以的。 今天换了下目录&#xff0c;重新安装&#xff0c;一直报错。 然后我们来看一下问题&#xff1a; mysqld -console 这里的目录是有问题的&#xff0c;设置的是&#xff1a;datadird:\to…