每日一题——Python实现PAT乙级1100 校庆(举一反三+思想解读+逐步优化)五千字好文


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

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

Python-3.12.0文档解读

目录

我的写法

代码结构和逻辑

时间复杂度分析

空间复杂度分析

总结

我要更强

方法一:直接处理输入,减少重复操作

优化点:

优化后的代码:

时间和空间复杂度分析:

方法二:预处理和一次遍历

优化点:

优化后的代码:

总结:

哲学和编程思想

举一反三


题目链接:https://pintia.cn/problem-sets/994805260223102976/exam/problems/type/7?problemSetProblemId=1478633948431106048&page=0

我的写法

# 读取输入的整数 N,表示朋友的数量
N = int(input())# 创建一个空的集合来存储朋友的名字
friends = set()# 初始化最老朋友的生日为一个较大的日期数值(20190101)
# 初始化最老朋友的名字为空字符串
oldest_friend_birthday = 20190101
oldest_friend = ""# 循环读取每一个朋友的信息
for i in range(N):# 读取朋友的名字(假设包含生日信息)friend = input()# 将朋友添加到集合中friends.add(friend)# 提取朋友的生日信息,假设生日是名字的第6到第14个字符tmp = int(friend[6:14])# 检查当前朋友是否比已知的最老朋友更老if tmp < oldest_friend_birthday:# 更新最老朋友的生日和名字oldest_friend_birthday = tmpoldest_friend = friend# 读取输入的整数 M,表示参与聚会的人数
M = int(input())# 初始化最老的非朋友的生日为一个较大的日期数值(20190101)
# 初始化最老的非朋友的名字为空字符串
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""# 初始化出席的朋友的计数器
came_friends_num = 0# 循环读取每一个出席者的信息
for i in range(M):# 读取出席者的名字came = input()# 提取出席者的生日信息,假设生日是名字的第6到第14个字符tmp = int(came[6:14])# 检查出席者是否在朋友集合中if came in friends:# 如果是朋友,计数器增加came_friends_num += 1else:# 如果不是朋友,检查他们是否比已知的最老非朋友更老if tmp < oldest_not_friend_birthday:# 更新最老非朋友的生日和名字oldest_not_friend = cameoldest_not_friend_birthday = tmp# 输出出席的朋友数量
print(came_friends_num)# 如果有朋友出席,输出最老的朋友,否则输出最老的非朋友
if came_friends_num > 0:print(oldest_friend)
else:print(oldest_not_friend)

代码结构和逻辑

  1. 输入处理:
    • 代码首先读取校友的数量 N,然后读取每个校友的信息并存储在集合 friends 中。同时,它还会记录最老的校友信息。
    • 接着,代码读取参与校友会的人员数量 M,然后读取每个参与者的信息。对于每个参与者,代码会检查他们是否在 friends 集合中,并记录出席的校友数量。如果不是校友,代码会记录最老的非校友信息。
  2. 输出结果:
  • 最后,代码输出出席的校友数量,以及最老的校友或最老的非校友。

时间复杂度分析

  • 校友信息处理:
    • 读取和处理每个校友的信息需要 O(N) 时间,因为每个校友的信息都需要被读取和处理一次。
    • 查找最老的校友信息在最坏情况下需要遍历所有校友,因此也是 O(N) 时间。
  • 参与校友会人员信息处理:
  • 读取和处理每个参与者的信息需要 O(M) 时间,因为每个参与者的信息都需要被读取和处理一次。
  • 检查每个参与者是否在 friends 集合中需要 O(1) 时间(因为集合的查找操作是常数时间)。
  • 查找最老的非校友信息在最坏情况下需要遍历所有非校友,因此也是 O(M) 时间。

综合来看,整个代码的时间复杂度是 O(N + M)。

空间复杂度分析

  • 校友信息存储:
    • 存储所有校友的信息需要 O(N) 空间,因为每个校友的信息都被存储在集合 friends 中。
  • 参与校友会人员信息存储:
  • 存储最老的校友和最老的非校友信息需要常数空间,即 O(1) 空间。

综合来看,整个代码的空间复杂度是 O(N)。

总结

  • 时间复杂度:O(N + M)
  • 空间复杂度:O(N)

这段代码在时间和空间复杂度上都是高效的,特别是利用集合进行快速查找操作,使得整体性能得到了优化。


我要更强

在这个特定的场景下,优化时间复杂度和空间复杂度的余地并不是很大,因为我们需要处理和检查每个校友和参与者的信息。不过,我们可以考虑一些细微的改进来使代码更简洁和高效。

方法一:直接处理输入,减少重复操作

优化点:
  1. 直接在读取输入时做判断和记录,减少不必要的集合操作。
  2. 尽量合并条件判断逻辑,减少代码分支。

优化后的代码:

# 读取输入的整数 N,表示校友的数量
N = int(input())# 初始化集合作为校友的集合
friends = set()# 初始化最老校友的生日和名字
oldest_friend_birthday = 20190101
oldest_friend = ""# 读取每个校友的信息并处理
for _ in range(N):friend = input()friends.add(friend)birthday = int(friend[6:14])if birthday < oldest_friend_birthday:oldest_friend_birthday = birthdayoldest_friend = friend# 读取输入的整数 M,表示参与校友会的人数
M = int(input())# 初始化最老非校友的生日和名字
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""# 出席的校友数量
came_friends_num = 0# 读取每个出席者的信息并处理
for _ in range(M):participant = input()birthday = int(participant[6:14])if participant in friends:came_friends_num += 1else:if birthday < oldest_not_friend_birthday:oldest_not_friend_birthday = birthdayoldest_not_friend = participant# 输出出席的校友数量
print(came_friends_num)# 如果有校友出席,输出最老的校友,否则输出最老的非校友
if came_friends_num > 0:print(oldest_friend)
else:print(oldest_not_friend)

时间和空间复杂度分析:

  1. 时间复杂度:
    • 处理 N 个校友的信息:O(N)
    • 处理 M 个参与者的信息:O(M)
    • 综合时间复杂度:O(N + M)
  2. 空间复杂度:
  • 存储 N 个校友的信息:O(N)
  • 其他变量消耗的空间为常数级别:O(1)
  • 综合空间复杂度:O(N)

方法二:预处理和一次遍历

优化点:
  1. 在读取校友信息和参与者信息时,尽量减少不必要的变量和集合操作。
  2. 尽量使用单次遍历完成所有处理。

优化后的代码:

# 读取输入的整数 N,表示校友的数量
N = int(input())# 初始化集合作为校友的集合
friends = set()# 初始化最老校友的生日和名字
oldest_friend_birthday = 20190101
oldest_friend = ""# 读取每个校友的信息并处理
for _ in range(N):friend = input()friends.add(friend)birthday = int(friend[6:14])if birthday < oldest_friend_birthday:oldest_friend_birthday = birthdayoldest_friend = friend# 读取输入的整数 M,表示参与校友会的人数
M = int(input())# 初始化最老非校友的生日和名字
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""# 出席的校友数量
came_friends_num = 0# 读取每个出席者的信息并处理
for _ in range(M):participant = input()birthday = int(participant[6:14])if participant in friends:came_friends_num += 1else:if birthday < oldest_not_friend_birthday:oldest_not_friend_birthday = birthdayoldest_not_friend = participant# 输出出席的校友数量
print(came_friends_num)# 如果有校友出席,输出最老的校友,否则输出最老的非校友
if came_friends_num > 0:print(oldest_friend)
else:print(oldest_not_friend)

总结:

尽管在时间和空间复杂度上很难有进一步的优化空间,通过改进代码结构和逻辑,可以使代码更加简洁和高效。上述方法在保持原有复杂度的基础上,优化了代码的可读性和可维护性。


哲学和编程思想

在这些优化方法中,实际上运用了一些重要的编程原则和思想:

  1. DRY(Don't Repeat Yourself):就是避免重复的原则。我们尽量避免在代码中出现重复的或者相似的操作,比如我们在读取输入时就直接完成了一些检查和记录等操作,避免了之后再对这些数据进行额外的处理。
  2. 单一职责原则:这是面向对象编程中的一项基本原则,但也可以应用到函数式编程中。我们在处理每个参与者的信息时,只进行了与该参与者相关的操作(检查是否是校友、更新最老的非校友信息等),避免了将多个任务混在一起,使代码更清晰、更容易理解。
  3. 预先处理:在处理数据或解决问题之前,先进行一些预处理,可以让后续的操作更简单、更快。我们在读取校友信息时,就把他们存储在一个集合中,使得后续判断一个人是否是校友变得非常快速(集合的查找操作平均是 O(1) 时间复杂度)。
  4. 尽早返回:如果已经得到了最终结果,就应该尽早返回,避免进行不必要的操作。我们在找出出席的校友数量后,就可以根据这个数量决定输出最老的校友还是最老的非校友,而不需要再进行其他的检查或判断。
  5. KISS(Keep It Simple, Stupid):简单就是美。我们应该尽可能写出简单、直观、易于理解的代码。这也是我们在优化代码时的一个主要目标。
  6. YAGNI(You Ain't Gonna Need It):你不会需要它的原则。这是敏捷开发中的一项原则,指的是避免过早优化或添加不需要的功能。尽管我们讨论了一些优化方法,但其实在这个特定的场景下,原始的代码已经足够完成任务,无需过度优化。

Code Readability Counts:代码可读性很重要。一个好的代码应该是自解释的,尽可能减少注释的使用。在优化代码时,尽量让代码更简洁、更直观,以提高代码的可读性。


举一反三

  1. 数据结构选择:正确选择合适的数据结构可以极大地提升代码的性能。例如,在这个案例中,我们使用集合(set)来存储校友信息,因为集合的查找时间复杂度是O(1),这对于检查某人是否是校友而言是非常有效的。
  2. 预处理数据:当需要多次使用到某些数据或结果时,可以考虑预处理并存储这些数据或结果,以减少重复计算,提升代码运行效率。在这个案例中,我们预先读取并处理了所有的校友信息。
  3. 合并逻辑:当可能的时候,尝试合并处理逻辑,减少代码分支,这不仅可以提高代码的可读性,还能在一定程度上提高代码的效率。例如,我们在处理参与者信息时,将校友和非校友的处理逻辑合并,避免了额外的条件分支。
  4. 尽早筛选和返回:当代码中有多个可能的输出或结果时,可以通过尽早筛选并返回结果来提高代码的效率。例如,在我们的案例中,我们根据出席的校友数量尽早确定了输出的是最老的校友还是最老的非校友。
  5. 优化代码可读性:良好的代码可读性非常重要,它可以帮助你和其他开发者更容易地理解和维护代码。你可以通过合理的命名、保持函数/方法的单一职责、适当的注释等方式来提高代码的可读性。
  6. 避免过早优化:虽然优化是一个好的实践,但过早地进行优化可能会使代码变得复杂且难以理解。你应该首先确保代码的正确性,然后在必要的时候进行适当的优化。

以上就是基于这个案例和编程原则,可以学习并举一反三的一些技巧。


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

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

相关文章

什么美业门店管理系统好用?2024美业收银系统软件排名分享

美业SAAS系统在美容、美发、美甲等行业中十分重要&#xff0c;这种系统为美业提供了一种数字化解决方案&#xff0c;帮助企业更高效地管理业务和客户关系。 美业门店管理系统通常提供预约管理、客户管理、库存管理、报表生成等一系列功能&#xff0c;以满足美容院、美发沙龙等…

【AIGC评测体系】大模型评测指标集

大模型评测指标集 &#xff08;☆&#xff09;SuperCLUE&#xff08;1&#xff09;SuperCLUE-V&#xff08;中文原生多模态理解测评基准&#xff09;&#xff08;2&#xff09;SuperCLUE-Auto&#xff08;汽车大模型测评基准&#xff09;&#xff08;3&#xff09;AIGVBench-T2…

Linux 实现自定义系统调用,支持参数和结果返回

本文实现一个简单的系统调用实现&#xff0c;支持输入字符串参数&#xff0c;并返回一个结果字符串。 以下是验证步骤&#xff1a; 1. 添加系统调用编号 试验使用的是 x86_64 架构的 Linux 内核。 找到并编辑 arch/x86/entry/syscalls/syscall_64.tbl 文件&#xff0c;在文件…

《每天5分钟用Flask搭建一个管理系统》第2章:项目结构与配置

第2章&#xff1a;项目结构与配置 2.1 Flask项目目录结构 一个典型的Flask项目可能包含以下目录和文件&#xff1a; /app - 应用目录 __init__.py - 初始化Flask应用models.py - 数据模型定义views.py - 视图函数定义forms.py - 表单类定义 /config - 配置文件目录 config.p…

机械行业常见问题及ERP解决办法

机械行业在全球经济一体化和技术进步背景下&#xff0c;面临着越来越多的挑战。为了在激烈的市场竞争中立于不败之地&#xff0c;企业需要找到合适的方法优化生产流程、降低成本、提升客户满意度。因此&#xff0c;有效地利用企业资源规划&#xff08;ERP&#xff09;解决方案变…

下标引用操作符;函数调用操作符;结构成员访问操作符

[] --- 下标引用操作符 下标引用操作符的操作数&#xff1a; 一个数组名 一个索引值 代码演示&#xff1a; #include<stdio.h> int main() {//创建数组int arr[5] { 1,2,3,4,5 }; // 数组下标&#xff1a; 0 1 2 3 4 //找到数组中3的元素并打印prin…

C# new关键字的三种用法

在C#中&#xff0c;new关键字具有多种不同的用途&#xff0c;主要包括以下三个&#xff1a; 1.作为运算符&#xff1a; 创建对象和调用构造函数&#xff1a;这是最常见的用法&#xff0c;用于在堆上分配内存并初始化一个类的新实例。例如&#xff1a; Person person new Pe…

从docker容器中导出单个表或整个数据库

首先你的服务器中已经有mysql容器进入到mysql容器中来 docker exec -it mysql /bin/bash 执行mysqldump命令导出数据 mysqldump -u root -p civil tb_user > product_info.sql# civil是数据库 # tb_user 是表名 # product_info.sql 是要保存数据的sql文件 上面这条命令会把…

65.WEB渗透测试-信息收集- WAF、框架组件识别(5)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;64.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;4&#xff09;-CSDN博客 waf绕…

从0开始学习pyspark--Spark DataFrame数据的选取与访问[第5节]

在PySpark中&#xff0c;选择和访问数据是处理Spark DataFrame的基本操作。以下是一些常用的方法来选择和访问DataFrame中的数据。 选择列&#xff08;Selecting Columns&#xff09;: select: 用于选择DataFrame中的特定列。selectExpr: 用于通过SQL表达式选择列。 df.select…

DSSAT作物模建模实践方法

随着数字农业和智慧农业的发展&#xff0c;基于过程的作物生长模型&#xff08;Process-based Crop Growth Simulation Model&#xff09;在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农业碳中和、农田固碳减排等领域扮演着越来越重要的作用。Decisi…

BMA580 运动传感器

型号简介 BMA580是博世&#xff08;bosch-sensortec&#xff09;的一款先进的、超小型加速度传感器。具有独特的骨传导语音活动检测功能和先进的功率模式功能&#xff0c;是世界上最小的加速度传感器&#xff08;1.2 x 0.8 x 0.55 mm&#xff09;。它专为紧凑型设备&#xff08…

多自由度平台资料网站连接

PLC控制的4点调平系统 - 豆丁网 (docin.com) 三自由度运动平台系统建模与分析 - 豆丁网 (docin.com) 四足机器人&#xff08;三&#xff09;--- 姿态控制_四足机器人姿态控制-CSDN博客

刀片服务器和机架式服务器有何区别

刀片服务器和机架式服务器有何区别 一、物理设计&#xff1a; 刀片服务器&#xff1a;刀片服务器是一种相对较轻薄的服务器设计&#xff0c;其物理形状类似于刀片&#xff0c;通常插入到专用的刀片机箱中。每个刀片通常包含一个或多个服务器节点&#xff0c;共享一些基本的资源…

Postman编写测试脚本

在 Postman 中&#xff0c;编写测试脚本通常使用 JavaScript&#xff0c;这些脚本可以在请求发送前后执行。以下是一些示例代码&#xff0c;展示了如何在 Postman 中使用测试脚本。 1. 测试脚本示例&#xff1a;检查响应状态码 // 测试脚本在请求发送后执行 pm.test("Re…

2024年建筑八大员(质量员-土建专业)考试题库。全面提升考试成绩,轻松过级!

1.砖基础施工时&#xff0c;砖基础的转角处和交接处应同时砌筑&#xff0c;当不能同时砌筑时&#xff0c;应留置&#xff08;&#xff09;。 A.直槎 B.凸槎 C.凹槎 D.斜槎 答案&#xff1a;D 2.分项工程施工前技术准备工作&#xff0c;主要指把拟定的分项工程施工前所需要…

Python的库dataperp读取excel和csv

领导说这个很牛&#xff0c;不过咱们不能听别人一口之言&#xff0c;咱们应该亲手试试&#xff0c;在来说这个好或者不好。 这个dataprepe已经不维护了&#xff0c;最高只支持python3.11以下版本,建议选择3.9. 他只能处理dataframe格式的数据&#xff0c;也就是pandas加载后的数…

穿梭在Yarn的代理配置迷宫:全面指南

&#x1f9f6; 穿梭在Yarn的代理配置迷宫&#xff1a;全面指南 Yarn是一个现代的包管理器&#xff0c;用于JavaScript应用程序&#xff0c;它提供了快速、可靠和安全的依赖管理。然而&#xff0c;在某些网络环境下&#xff0c;例如公司内网或需要通过代理服务器访问外部资源时…

Python模拟火焰文字效果:炫酷的火焰字动效

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame定义火焰效果类主循环 完整代码 引言 火焰文字效果是一种炫酷的视觉效果&#xff0c;常用于广告、游戏和艺术设计中。在这篇博客中&#xff0c;我们将使用Python创建一个火焰文字的动画效果。通过利用Py…

TON、Solana 和 以太坊 2.0 的对比

自 2017 年编写最初的 TON 白皮书[1] 以来&#xff0c;出现了许多新的区块链项目&#xff0c;例如 Solana 和 Ethereum 2.0。在本文中&#xff0c;我们将 TON 与其中一些比较有代表性的区块链项目进行了对比。 1. 对比形式 根据 TON 原白皮书第2.8 和2.9 节对区块链项目的分类…