每日一题——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;在文件…

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

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

C# new关键字的三种用法

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

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

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

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…

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加载后的数…

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

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

前端开发中的常见问题及解决方法

前端开发是一个充满挑战和乐趣的领域。然而&#xff0c;在开发过程中&#xff0c;开发者常常会遇到各种各样的问题。本文将介绍一些前端开发中常用或者经常遇到的问题&#xff0c;并提供相应的解决方法&#xff0c;帮助你提高开发效率和解决问题的能力。 一. 页面布局问题 问题…

【启明智显技术分享】SSD202D核心板方案双网口SBC2D06开发板开箱与实操全攻略上手指南

一、背景 本指南将详细介绍启明智显基于SSD202D核心板方案下的双网口-SBC2D06的开箱及实操上手应用。无论您是电子爱好者、开发者还是工程师&#xff0c;这份指南都能助您快速上手并充分利用这款双网口开发板的各项功能。 二、硬件介绍 SBC2D06双网口开发板&#xff0c;作为…

Flink实现准确和高效流处理的关键问题

时间相关: Watermark 水位线 水位线是插入到数据流中的一个标记,可以认为是一个特殊的数据。水位线主要的内容是一个时间戳,用来表示当前事件时间的进展。水位线是基于数据的时间戳生成的。水位线的时间戳必须单调递增,以确保任务的事件时间时钟一直向前推进,进展。水位线…

香橙派OrangePi AIpro初体验:当小白拿到一块开发板第一时间会做什么?

文章目录 香橙派OrangePi AIpro初体验&#xff1a;当小白拿到一块高性能AI开发板第一时间会做什么前言一、香橙派OrangePi AIpro概述1.简介2.引脚图开箱图片 二、使用体验1.基础操作2.软件工具分析 三、香橙派OrangePi AIpro.测试Demo1.测试Demo1&#xff1a;录音和播音(USB接口…

渲染100农场如何渲染全景图?渲染100邀请码1a12

全景图的制作需要渲染&#xff0c;以国内知名的渲染农场—渲染100为例&#xff0c;我来说下操作过程。 1、进入渲染100官网&#xff0c;点击右上角注册按钮完成注册&#xff0c;记得邀请码一栏填1a12&#xff0c;有30元礼包和2张免费渲染券。 渲染100官网&#xff1a;http://…

构建LangChain应用程序的示例代码:50、如何在检索-生成 (RAG) 应用中利用多模态大型语言模型 (LLM) 处理包含文本和图像的混合文档的示例

多模态 RAG 许多文档包含多种内容类型&#xff0c;包括文本和图像。 然而&#xff0c;大多数 RAG 应用中&#xff0c;图像中捕获的信息往往被忽略。 随着多模态 LLM 的出现&#xff0c;如 GPT-4V&#xff0c;值得考虑如何在 RAG 中利用图像&#xff1a; 选项 1&#xff1a;…

【实战】EasyExcel实现百万级数据导入导出

文章目录 前言技术积累实战演示实现思路模拟代码测试结果 前言 最近接到一个百万级excel数据导入导出的需求&#xff0c;大概就是我们在进行公众号API群发的时候&#xff0c;需要支持500w以上的openid进行群发&#xff0c;并且可以提供发送openid数据的导出功能。可能有的同学…

Android项目框架

Android项目基于Android Studio开发&#xff0c;Android Studio使用Gradle作为项目构建工具。新建工程后可以看到如图所示目录结构&#xff0c;将Android切成Project可以看到完整的Android工程目录结构&#xff0c;如图所示。 图1-2 Android项目目录结构 app目录是一个典型的…

Profibus转Modbus网关在智能化水处理系统优化改造的应用

一、背景 在现代水处理行业中&#xff0c;智能化系统的应用已经成为提高效率和降低成本的关键。特别是在水厂中&#xff0c;罐内压载水处理系统的自动化和监控对于保障水质安全至关重要。而在这一过程中需要将水泵、阀门、传感器等设备连接到中控系统上。 二、方案 在控制器与…