每日一题——Python实现PAT乙级1072 开学寄语(举一反三+思想解读+逐步优化)五千字好文


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

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

Python-3.12.0文档解读

目录

我的写法

代码点评

时间复杂度分析

空间复杂度分析

总结

我要更强

优化建议

优化后的代码

代码注释

时间复杂度和空间复杂度分析

哲学和编程思想

抽象与封装:

效率与优化:

简洁与清晰:

不变性与可变性:

DRY原则(Don't Repeat Yourself):

KISS原则(Keep It Simple, Stupid):

YAGNI原则(You Ain't Gonna Need It):

单一职责原则(Single Responsibility Principle):

开闭原则(Open/Closed Principle):

举一反三


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

我的写法

inputs=input().split()
n=int(inputs[0])
m=int(inputs[1])

forbid_items=input().split()
out_stu_num=0
out_item_num=0


for i in range(n):
    inputs=input().split()
    name=inputs[0]
    person_items=inputs[2:]
    tmp=[]
    
    for person_item in person_items:
        if person_item not in forbid_items:
            tmp.append(person_item)

    for i in tmp:
        person_items.remove(i)

    if person_items:
        print(f"{name}:",end='')
        for person_item in person_items:
            print(f" {person_item}",end='')
        print()
        out_stu_num+=1
        out_item_num+=len(person_items)
        

print(f"{out_stu_num} {out_item_num}")

这段代码的功能是处理学生携带物品的问题。具体来说,它读取学生数量 n 和禁止携带的物品数量 m,然后读取禁止携带的物品列表。接着,对于每个学生,它读取学生的姓名和携带的物品,并检查这些物品是否在禁止携带的物品列表中。如果是,则输出该学生的姓名和禁止携带的物品,并记录违规的学生数量和物品数量。

代码点评

  1. 输入处理:
    • 代码使用了 input().split() 来读取输入,这是一种常见的处理方式。
    • 通过 int(inputs[0]) 和 int(inputs[1]) 分别获取学生数量 n 和禁止携带的物品数量 m,这是合理的。
  2. 数据结构:
    • 使用列表 forbid_items 来存储禁止携带的物品,这是合适的选择。
    • 使用 person_items 来存储每个学生携带的物品,这也是合适的选择。
  3. 逻辑处理:
    • 代码通过嵌套的 for 循环来检查每个学生携带的物品是否在禁止携带的物品列表中。
    • 使用 tmp 列表来存储允许携带的物品,然后从 person_items 中移除这些物品,这是一种有效的方法。
  4. 输出处理:
  • 代码通过 print 函数输出违规学生的姓名和物品,格式化输出是合理的。
  • 最后输出违规学生的总数和物品总数,这也是合理的。

时间复杂度分析

  • 输入处理:读取输入的时间复杂度是 O(n + m)。
  • 检查物品:对于每个学生,检查每个物品是否在禁止携带的物品列表中的时间复杂度是 O(n * k),其中 k 是每个学生携带的物品数量。
  • 移除物品:从 person_items 中移除物品的时间复杂度是 O(k)。

综合来看,整体时间复杂度是 O(n * k),其中 k 是每个学生携带的物品数量的平均值。

空间复杂度分析

  • 输入存储:存储学生数量 n 和禁止携带的物品数量 m 的空间复杂度是 O(1)。
  • 禁止携带物品列表:存储禁止携带的物品列表的空间复杂度是 O(m)。
  • 学生携带物品列表:存储每个学生携带的物品列表的空间复杂度是 O(n * k)。

综合来看,整体空间复杂度是 O(m + n * k)。

总结

  • 优点:代码结构清晰,逻辑处理合理,能够正确处理输入并输出结果。
  • 缺点:在移除物品时,使用 person_items.remove(i) 可能会导致线性时间复杂度,因为列表的 remove 操作是 O(k) 的。可以考虑使用集合(set)来优化这一部分。

改进建议:可以使用集合(set)来存储禁止携带的物品列表,这样可以优化检查物品是否在禁止携带列表中的时间复杂度。同时,可以使用集合来存储每个学生携带的物品,以优化移除物品的操作。


我要更强

优化时间复杂度和空间复杂度的方法通常涉及使用更高效的数据结构和算法。以下是一些优化建议,并附上相应的代码和注释。

优化建议

  1. 使用集合(Set):
    • 使用集合来存储禁止携带的物品列表,这样可以优化检查物品是否在禁止携带列表中的时间复杂度。
    • 使用集合来存储每个学生携带的物品,以优化移除物品的操作。
  2. 减少不必要的操作:
  • 避免在循环中多次调用 input().split(),可以一次性读取所有输入并存储在列表中。

优化后的代码

# 读取学生数量和禁止携带的物品数量
n, m = map(int, input().split())

# 读取禁止携带的物品列表并转换为集合
forbid_items = set(input().split())

# 初始化违规学生数量和物品数量
out_stu_num = 0
out_item_num = 0

# 读取所有学生的输入并存储在列表中
students = [input().split() for _ in range(n)]

# 处理每个学生的输入
for inputs in students:
    name = inputs[0]
    person_items = set(inputs[2:])  # 将学生携带的物品转换为集合

    # 找出禁止携带的物品
    forbidden_items = person_items & forbid_items

    # 如果有禁止携带的物品
    if forbidden_items:
        print(f"{name}:", end='')
        for item in forbidden_items:
            print(f" {item}", end='')
        print()
        out_stu_num += 1
        out_item_num += len(forbidden_items)

# 输出违规学生的总数和物品总数
print(f"{out_stu_num} {out_item_num}")

代码注释

  1. 读取输入:
    • n, m = map(int, input().split()):读取学生数量和禁止携带的物品数量。
    • forbid_items = set(input().split()):读取禁止携带的物品列表并转换为集合。
  2. 初始化计数器:
    • out_stu_num = 0 和 out_item_num = 0:初始化违规学生数量和物品数量。
  3. 读取所有学生的输入:
    • students = [input().split() for _ in range(n)]:一次性读取所有学生的输入并存储在列表中。
  4. 处理每个学生的输入:
    • name = inputs[0]:获取学生姓名。
    • person_items = set(inputs[2:]):将学生携带的物品转换为集合。
    • forbidden_items = person_items & forbid_items:找出禁止携带的物品。
    • 如果有禁止携带的物品,输出学生姓名和禁止携带的物品,并更新违规学生数量和物品数量。
  5. 输出结果:
  • print(f"{out_stu_num} {out_item_num}"):输出违规学生的总数和物品总数。

时间复杂度和空间复杂度分析

  • 时间复杂度:
    • 读取输入的时间复杂度是 O(n + m)。
    • 检查物品的时间复杂度是 O(n * k),其中 k 是每个学生携带的物品数量的平均值。
    • 使用集合的交集操作 & 的时间复杂度是 O(min(a, b)),其中 a 和 b 分别是两个集合的大小。
  • 空间复杂度:
  • 存储学生数量 n 和禁止携带的物品数量 m 的空间复杂度是 O(1)。
  • 存储禁止携带的物品列表的空间复杂度是 O(m)。
  • 存储每个学生携带的物品列表的空间复杂度是 O(n * k)。

通过使用集合,代码在检查物品和移除物品的操作上更加高效,从而优化了时间复杂度和空间复杂度。


哲学和编程思想

这些优化方法体现了以下哲学和编程思想:

  1. 抽象与封装:

    • 哲学思想:抽象是指从具体事物中提取出共同的、本质的特征,忽略非本质的细节。封装是将数据和操作数据的方法组合在一起,形成一个独立的单元。
    • 编程思想:在代码中,我们将输入处理、数据存储和逻辑处理分别封装在不同的部分,使得代码结构清晰,易于理解和维护。
  2. 效率与优化:

    • 哲学思想:效率是指在单位时间内完成的工作量,优化是指通过改进方法或工具来提高效率。
    • 编程思想:我们使用集合(Set)来存储禁止携带的物品列表和学生携带的物品,这样可以利用集合的高效查找特性来优化检查物品是否在禁止携带列表中的时间复杂度。
  3. 简洁与清晰:

    • 哲学思想:简洁是指简单明了,不复杂;清晰是指清楚明白,易于理解。
    • 编程思想:代码中避免冗余和复杂的逻辑,使用简洁的语法和结构,使得代码易于阅读和理解。
  4. 不变性与可变性:

    • 哲学思想:不变性是指事物保持不变的特性,可变性是指事物可以改变的特性。
    • 编程思想:在代码中,我们使用集合来存储物品,集合是可变的,但我们可以通过集合的交集操作来获取不变的结果,这样可以保持逻辑的稳定性和可预测性。
  5. DRY原则(Don't Repeat Yourself):

    • 哲学思想:DRY原则是指避免重复代码,通过抽象和封装来减少重复。
    • 编程思想:在代码中,我们避免重复读取输入和处理逻辑,通过一次性读取所有输入并存储在列表中,减少了重复操作。
  6. KISS原则(Keep It Simple, Stupid):

    • 哲学思想:KISS原则是指保持简单,避免不必要的复杂性。
    • 编程思想:代码中我们尽量保持简单,避免过度设计,使用简单的数据结构和直接的逻辑处理。
  7. YAGNI原则(You Ain't Gonna Need It):

    • 哲学思想:YAGNI原则是指仅实现当前需要的功能,避免预先设计复杂的功能。
    • 编程思想:在代码中,我们仅实现当前需要的功能,不预先设计复杂的数据结构,而是根据实际需求逐步优化。
  8. 单一职责原则(Single Responsibility Principle):

    • 哲学思想:单一职责原则是指一个模块或类应该只有一个引起它变化的原因。
    • 编程思想:在代码中,每个函数或模块只负责一个功能,例如读取输入、处理逻辑和输出结果,这样可以提高代码的内聚性。
  9. 开闭原则(Open/Closed Principle):

  • 哲学思想:开闭原则是指软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  • 编程思想:在代码中,我们设计可扩展的接口,例如使用集合来存储物品,这样可以方便地在将来需要时添加新功能,而不需要修改现有代码。

通过应用这些哲学和编程思想,代码不仅在性能上得到了优化,而且在结构和设计上更加合理和高效。


举一反三

根据上述哲学和编程思想,以及本题目的情况,以下是一些技巧,可以帮助你在编程时举一反三,提高代码的质量和效率:

  1. 抽象与封装:
    • 技巧:将复杂的问题分解为更小的、可管理的部分。每个部分负责一个特定的功能,并通过接口进行交互。这样可以使代码更加模块化和易于维护。
    • 应用:在处理复杂的数据结构或算法时,可以创建专门的类或函数来处理特定的任务,而不是将所有逻辑混在一起。
  2. 效率与优化:
    • 技巧:选择合适的数据结构和算法来解决问题。了解不同数据结构和算法的性能特点,并根据问题的需求进行选择。
    • 应用:在需要频繁查找或插入操作时,考虑使用哈希表(如Python中的字典)或集合(Set)。在需要排序时,考虑使用快速排序或归并排序。
  3. 简洁与清晰:
    • 技巧:编写简洁、清晰的代码。避免不必要的复杂性,使用有意义的变量名和函数名,以及清晰的注释。
    • 应用:在编写代码时,尽量使用Python的内置函数和库,避免自己实现已经存在的功能。
  4. 不变性与可变性:
    • 技巧:在设计数据结构时,考虑使用不可变对象(如元组)来避免副作用。在需要修改数据时,考虑使用可变对象(如列表)。
    • 应用:在处理并发或需要保证数据一致性的场景中,使用不可变对象可以减少错误。
  5. DRY原则:
    • 技巧:识别和消除重复代码。通过函数或类来封装重复的逻辑,并在需要的地方调用它们。
    • 应用:在多个地方使用相同的逻辑时,创建一个函数或方法来封装这些逻辑,并在需要的地方调用。
  6. KISS原则:
    • 技巧:保持代码简单。避免过度设计,仅实现当前需要的功能。
    • 应用:在设计新功能时,先实现最简单的版本,然后根据反馈逐步优化。
  7. YAGNI原则:
    • 技巧:仅实现当前需要的功能,避免预先设计复杂的功能。
    • 应用:在项目初期,不要过度设计未来的功能。随着项目的进展,根据实际需求逐步添加功能。
  8. 单一职责原则:
    • 技巧:确保每个类或函数只负责一个功能。这样可以提高代码的可读性和可维护性。
    • 应用:在设计类或函数时,确保它们只做一件事,并且做得好。
  9. 开闭原则:
  • 技巧:设计可扩展的接口,使得在不修改现有代码的情况下可以添加新功能。
  • 应用:在设计类或模块时,考虑未来的扩展需求,并设计相应的接口。

通过应用这些技巧,可以在编程时更加灵活和高效,不仅能够解决当前的问题,还能够为未来的需求做好准备。记住,编程是一个不断学习和改进的过程,不断实践这些原则和技巧,编程能力将会不断提高。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

百度ueditor如何修改图片的保存位置

背景 编辑器的保存图片是设置有默认规则的,但是服务器上一般会把图片路径设置为软连接,所以我就需要更改编辑器保存图片的路径,要不然,每次有新的部署,上一次上传的图片就会失效。先来看看编辑器默认的保存路径吧&…

二进制方式部署consul单机版

1.consul的下载 mkdir -p /root/consul/data && cd /root/consul wget https://releases.hashicorp.com/consul/1.18.0/consul_1.18.0_linux_amd64.zip unzip consul_1.18.0_linux_amd64.zip mv consul /usr/local/bin/ 2.配置文件 // 配置文件路径: /roo…

[算法]——堆排序(C语言实现)

简单的介绍一下用堆排序的算法对整形数据的数据进行排序。 一、堆的概念 堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。 …

第二十一课,列表的操作函数

一,len(列表):求列表的长度 当你需要知道一个列表中含有多少个元素时,可以使用len()函数,将列表的变量名放入len()函数的括号中,它将告诉你这个列表中有多少个元素,也就是它的长度! 需要注意的是&#xf…

安装OpenHarmony编译库和工具集

一、搭建开发环境 1.1、Ubuntu搭建,参考 VMware完美安装Ubuntu20.04-CSDN博客文章浏览阅读286次,点赞5次,收藏3次。详细介绍了VMware下安装Ubuntu20.04https://blog.csdn.net/longyuzi/article/details/139935769 1.2、拉取OpenHarmony源码…

实现自动化:如何利用阿里云OSS上传文件并自动打标签

在当前数字化时代,数据管理变得愈发重要,特别是对于需要大规模存储和管理文件的场景。阿里云对象存储服务(OSS)作为业界领先的解决方案,不仅提供了稳定可靠的云存储,还支持丰富的扩展功能,如文件…

每日一道算法题 面试题 08.08. 有重复字符串的排列组合

题目 面试题 08.08. 有重复字符串的排列组合 - 力扣(LeetCode) Python class Solution:def permutation(self, S: str) -> List[str]:# 以索引记录字符是否用过lelen(S)idx[_ for _ in range(le) ]# 组合得到的字符串combine[]*leans[]# 递归def fu…

LLM探索:环境搭建与模型本地部署

前言 最近一直在炼丹(搞AIGC这块),突然发现业务代码都索然无味了… 上次发了篇AI画图的文章,ChatGPT虽然没法自己部署,但现在开源的LLM还是不少的,只要有一块差不多的显卡,要搞个LLM本地部署还…

安卓应用开发学习:获取经纬度及地理位置描述信息

前段时间,我在学习鸿蒙应用开发的过程中,在鸿蒙系统的手机上实现了获取经纬度及地理位置描述信息(鸿蒙应用开发学习:手机位置信息进阶,从经纬度数据获取地理位置描述信息)。反而学习时间更长的安卓应用开发…

基于知识图谱的医药问答系统实战

数据及代码地址见文末 1.项目配置 (1)Neo4j数据库安装 JDK 安装:https://www.oracle.com/java/technologies/javase-downloads.html Neo4j 安装:https://neo4j.com/download-center/ 配置好 JDK 和 Neo4j 的环境变量 启动:neo4j.bat console 第一次启动有默认用户名和密…

《昇思25天学习打卡营第3天|张量 Tensor》

文章目录 前言:今日所学:1. 创建张量2. 张量的属性3.张量索引与运算4. NumPy与Tensor的转换5. 稀疏张量 前言: 张量?张亮?张量是什么? 张量是一个可以用来表示在一些矢量、标量和其他张量之间的线性关系的…

逆风而行:提升逆商,让困难成为你前进的动力

一、引言 生活,总是充满了未知与变数。有时,我们会遇到阳光明媚的日子,享受着宁静与和谐;但更多时候,我们却不得不面对那些突如其来的坏事件,如工作的挫折、人际关系的困扰、健康的挑战等。这些事件如同突…

每日一题——Python实现PAT乙级1059 C语言竞赛(举一反三+思想解读+逐步优化)四千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 时间复杂度分析 空间复杂度分析 代码优化建议 总结 我要更强 优化方法…

秋招突击——第九弹——Redis缓存

文章目录 引言正文缓存基础旁路缓存模式(重点)读穿透(了解)写穿透(了解)异步缓存写入模式面试重点 缓存异常场景缓存穿透缓存击穿缓存雪崩面试重点 缓存一致性怎么保证?缓存一致性问题是什么方案…

使用SpringBoot整合filter

SpringBoot整合filter,和整合servlet类似,也有两种玩儿法 1、创建一个SpringBoot工程,在工程中创建一个filter过滤器,然后用注解WebFilter配置拦截的映射 2、启动类还是使用ServletComponentScan注解来扫描拦截器注解WebFilter 另…

Vue2中管理$bus事件,统一移除事件

1. vue2中使用了,很多bus,在有些地方忘记清理了,导致重复事件bug. 对bus进行改造,实现清除遗留. 下面的简单实现. 1.eventbus.js // eventBus.js import Vue from vue;class EventBusClass extends Vue {constructor() {super();this.listeners [];}on(event, callback, con…

实测备受好评的三款独享IP网站服务商

一、引言 在如今互联网快速发展的时代,网络爬虫、数据抓取等任务对于许多企业和个人来说愈发重要,而在这个过程中,一个稳定、高效且安全的独享IP资源显得尤为重要。作为专业的测评团队,我们深知一款优秀的独享IP服务商需要具备哪…

2-19 基于matlab的薄板弯曲的算例

基于matlab的薄板弯曲的算例,利用有限元方法编制matlab程序。对二维薄板进行单元化,输出薄板结构参数及载荷,输出弯曲情况,并可视化展示。程序已调通,可直接运行。 2-19 薄板弯曲 有限元方法 薄板结构参数 - 小红书 (x…

【MySQL】InnoDB架构

本文MySQL版本是8.X版本 这是官方文档给出来的架构图:MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture 可以看出,整体上是分成两部分的:内存结构(提高效率)和磁盘结构(数据持久化),下面将把每个区域都大致做一个…

Java程序员学习Go开发Higress的WASM插件

Java程序员学习Go开发Higress的WASM插件 契机 ⚙ 今年天池大赛有higress相关挑战,研究一下。之前没搞过go,踩了很多坑,最主要的就是tinygo打包,多方寻求解决无果,结论是tinygo0.32go1.19无法在macos arm架构下打包。…