每日一题——Python实现PAT甲级1028 List Sorting(举一反三+思想解读+逐步优化)

news2024/10/6 14:25:14


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

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

Python-3.12.0文档解读

目录

​编辑​编辑​编辑我的写法:

代码点评

代码点评:

时间复杂度分析:

空间复杂度分析:

总结:

我要更强!

时间复杂度优化:

空间复杂度优化:

总结:

哲学和编程思想

举一反三

1. 效率优先 - 使用内置函数和库

2. 原地操作 - 利用列表推导式

3. 模块化与解耦 - 使用函数和类

4. 抽象与泛化 - 使用高阶函数

5. 简单性原则 - 避免过度设计

6. 优化与平衡 - 选择合适的数据结构

7. 可读性与可维护性 - 添加注释和文档


题目链接


我的写法:

# 读取输入的第一行,将第一个值赋给 N,第二个值赋给 C
N, C = map(int, input().split())

# 创建一个空列表 inputs,用于存储后续输入的数据
inputs = []

# 循环 N 次,每次读取一行输入,并将输入分割成列表,添加到 inputs 中
for i in range(N):
    inputs.append(input().split())

# 根据 C 的值选择不同的排序方式
if C == 1:
    # 如果 C 为 1,则按照列表中的第一个元素进行排序
    inputs = sorted(inputs, key=lambda x: x[0])
elif C == 2:
    # 如果 C 为 2,则先按照列表中的第二个元素进行排序,如果相同则再按照第一个元素排序
    inputs = sorted(inputs, key=lambda x: (x[1], x[0]))
elif C == 3:
    # 如果 C 为 3,则先按照列表中的第三个元素(将其转换为整数)进行排序,如果相同则再按照第一个元素排序
    inputs = sorted(inputs, key=lambda x: (int(x[2]), x[0]))

# 遍历排序后的 inputs 列表
for elem in inputs:
    # 将列表中的元素连接成一个字符串,元素之间用空格分隔,并打印出来
    print(' '.join(elem))

代码点评

这段代码的主要功能是读取输入数据,根据指定的列进行排序,并输出排序后的结果。下面是对这段代码的专业点评以及时间复杂度和空间复杂度的分析:

代码点评:

  1. 输入处理:代码通过 input().split() 读取输入,并将它们分割成列表。这种方式简单直观,适用于处理简单的输入格式。
  2. 排序逻辑:根据变量 C 的值,代码使用不同的排序键。这种设计允许用户通过改变 C 的值来指定排序的列,增加了代码的灵活性。
  3. 排序实现:使用 Python 的内置 sorted 函数,并结合 lambda 函数定义排序键。这是一种常见的做法,可以有效地对列表进行排序。
  4. 输出格式:使用 ' '.join(elem) 将列表转换为字符串并打印,保持了输入时的格式,使得输出清晰易读。

时间复杂度分析:

  1. 输入处理:读取和分割输入的时间复杂度为 O(N),其中 N 是输入的行数。
  2. 排序:sorted 函数的时间复杂度为 O(N log N),因为它是基于比较的排序算法。
  3. 输出:打印输出的时间复杂度为 O(N),因为需要遍历整个排序后的列表。

因此,总体的时间复杂度为 O(N + N log N + N) = O(N log N),主要受排序操作的影响。

空间复杂度分析:

  1. 输入存储:存储输入数据的空间复杂度为 O(N),因为需要存储每一行的数据。
  2. 排序:sorted 函数在原地排序时不需要额外的空间,但由于这里将排序结果赋值给了 inputs,所以空间复杂度也是 O(N)。
  3. 输出:输出操作不需要额外的空间。

因此,总体的空间复杂度为 O(N),主要由存储输入数据决定。

总结:

这段代码在功能上是完整的,能够根据用户指定的列对输入数据进行排序并输出。时间复杂度主要受排序操作的影响,为 O(N log N),而空间复杂度为 O(N)。在实际应用中,如果输入数据量较大,可能需要考虑优化排序算法或使用更高效的数据结构来减少时间和空间的开销。


我要更强!

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

  1. 减少不必要的排序:如果输入数据已经按照某个顺序排列,或者可以通过其他方式快速确定排序顺序,可以避免使用 sorted 函数。
  2. 原地排序:如果不需要保留原始列表,可以使用 list.sort() 方法进行原地排序,这样可以减少空间复杂度。
  3. 输入和输出的优化:如果输入和输出是瓶颈,可以考虑使用更高效的输入输出方法,如使用 sys.stdin.readline() 代替 input()。

下面是一个优化后的代码示例,使用了原地排序和更高效的输入输出方法:

import sys

# 读取输入的第一行,将第一个值赋给 N,第二个值赋给 C
N, C = map(int, sys.stdin.readline().split())

# 创建一个空列表 inputs,用于存储后续输入的数据
inputs = []

# 循环 N 次,每次读取一行输入,并将输入分割成列表,添加到 inputs 中
for i in range(N):
    inputs.append(sys.stdin.readline().split())

# 根据 C 的值选择不同的排序方式
if C == 1:
    # 如果 C 为 1,则按照列表中的第一个元素进行排序
    inputs.sort(key=lambda x: x[0])
elif C == 2:
    # 如果 C 为 2,则先按照列表中的第二个元素进行排序,如果相同则再按照第一个元素排序
    inputs.sort(key=lambda x: (x[1], x[0]))
elif C == 3:
    # 如果 C 为 3,则先按照列表中的第三个元素(将其转换为整数)进行排序,如果相同则再按照第一个元素排序
    inputs.sort(key=lambda x: (int(x[2]), x[0]))

# 遍历排序后的 inputs 列表
for elem in inputs:
    # 将列表中的元素连接成一个字符串,元素之间用空格分隔,并打印出来
    print(' '.join(elem))

时间复杂度优化:

  • 使用 sys.stdin.readline() 代替 input() 可以减少输入操作的时间复杂度。
  • 原地排序 list.sort() 的时间复杂度仍然是 O(N log N),但避免了创建新的列表,减少了空间复杂度。

空间复杂度优化:

  • 原地排序 list.sort() 不创建新的列表,因此空间复杂度保持在 O(N)。

总结:

这段代码在保持原有功能的基础上,通过原地排序和优化输入输出方法,减少了空间使用并可能提高输入输出的效率。时间复杂度仍然是 O(N log N),空间复杂度是 O(N)。在处理大量数据时,这些优化可以带来显著的性能提升。


哲学和编程思想

这段优化后的代码体现了以下哲学和编程思想:

  1. 效率优先:通过使用 sys.stdin.readline() 代替 input(),代码减少了输入操作的时间复杂度,体现了在编程中追求效率的思想。这种思想强调在处理大量数据时,应该尽可能减少不必要的计算和资源消耗。
  2. 原地操作:使用 list.sort() 进行原地排序,而不是创建一个新的排序后的列表,这体现了“不增加额外空间”的哲学。原地操作是一种常见的优化策略,它通过减少内存使用来提高程序的效率。
  3. 模块化与解耦:代码中的排序逻辑根据变量 C 的值进行不同的处理,这种设计使得排序功能模块化,易于理解和维护。同时,这种解耦也使得代码更加灵活,可以通过改变 C 的值来适应不同的排序需求。
  4. 抽象与泛化:使用 lambda 函数定义排序键,这是一种抽象和泛化的编程技巧。通过定义一个简单的函数作为排序键,可以灵活地指定排序的依据,而不需要为每种排序规则编写一个具体的函数。
  5. 简单性原则:代码保持了简单直观的风格,没有引入复杂的数据结构或算法。这种简单性原则(KISS原则,Keep It Simple, Stupid)是软件工程中的一个重要思想,它强调在设计中应该尽可能保持简单,以减少错误和提高可维护性。
  6. 优化与平衡:在优化时间和空间复杂度时,代码需要在两者之间找到一个平衡点。这里通过原地排序减少了空间使用,同时通过优化输入输出方法提高了时间效率。这种平衡考虑是编程中的一个重要思想,它要求开发者在不同的优化目标之间做出权衡。
  7. 可读性与可维护性:代码中的注释和清晰的结构有助于提高代码的可读性和可维护性。这是软件开发中的一个重要原则,它强调代码不仅是用来执行的,也是用来被其他开发者理解和修改的。

通过这些哲学和编程思想的应用,优化后的代码不仅提高了性能,也增强了代码的可读性和可维护性,符合现代软件开发的最佳实践。


举一反三

根据上述的哲学和编程思想,以下是一些具体的技巧和示例代码,帮助你举一反三:

1. 效率优先 - 使用内置函数和库

使用 Python 的内置函数和库通常比自己编写的代码更高效。例如,使用 map() 函数可以快速将列表中的元素转换为另一种类型。

# 使用 map 快速转换列表中的元素类型
numbers = ['1', '2', '3', '4', '5']
integers = list(map(int, numbers))

2. 原地操作 - 利用列表推导式

列表推导式是一种原地操作的技巧,它可以快速生成新的列表而不需要额外的空间。

# 使用列表推导式过滤列表中的偶数
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [x for x in numbers if x % 2 == 0]

3. 模块化与解耦 - 使用函数和类

将代码分解为函数和类可以提高模块化和解耦。例如,创建一个函数来处理特定的排序逻辑。

def sort_by_criteria(data, criteria):
    if criteria == 1:
        return sorted(data, key=lambda x: x[0])
    elif criteria == 2:
        return sorted(data, key=lambda x: (x[1], x[0]))
    elif criteria == 3:
        return sorted(data, key=lambda x: (int(x[2]), x[0]))

# 使用函数进行排序
data = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
sorted_data = sort_by_criteria(data, 1)

4. 抽象与泛化 - 使用高阶函数

高阶函数如 map()、filter() 和 reduce() 可以接受函数作为参数,这使得代码更加抽象和泛化。

# 使用高阶函数 map 和 lambda 进行元素转换
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))

5. 简单性原则 - 避免过度设计

保持代码简单,避免引入不必要的复杂性。例如,如果一个简单的循环可以解决问题,就不要使用复杂的数据结构。

# 简单的循环解决问题
sum_of_numbers = 0
for num in numbers:
    sum_of_numbers += num

6. 优化与平衡 - 选择合适的数据结构

选择合适的数据结构可以平衡时间和空间复杂度。例如,使用集合(set)来快速查找元素。

# 使用集合快速查找元素
numbers = [1, 2, 3, 4, 5, 2, 3, 4]
unique_numbers = set(numbers)

7. 可读性与可维护性 - 添加注释和文档

为代码添加注释和文档可以提高其可读性和可维护性。

# 计算列表中所有元素的和
def sum_list(lst):
    """
    计算列表中所有元素的和。
    
    参数:
    lst (list): 包含数字的列表
    
    返回:
    int: 列表中所有元素的和
    """
    return sum(lst)

通过应用这些技巧,可以提高代码的效率、可读性和可维护性,同时保持代码的简洁和灵活。


感谢阅读。

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

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

相关文章

EasyExcel的CellWriteHandler注入CellStyle不生效

文章目录 一、问题描述二、问题排查三、解决问题 一、问题描述 最近发现原本项目的导出excel功能中,写的那些 CellWriteHandler 去改变样式的代码全都不生效了 二、问题排查 由于代码都是没有改动的,加上最近有升级过 easyExcel 的版本,由…

js实现鼠标拖拽多选功能

实现功能 在PC端的H5页面中&#xff0c;客户拖动鼠标可以连选多个选项 效果展示 具体代码如下 <!DOCTYPE html> <html><head><title>鼠标拖拽多选功能</title><script src"https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js&quo…

ArcGIS基础操作-ArcGIS插值交叉验证方法与流程

ArcGIS基础操作-ArcGIS插值交叉验证方法与流程 交叉验证(Cross-validation)主要用于建模应用中&#xff0c;例如PCR、PLS回归建模中。在给定的建模样本中&#xff0c;拿出大部分样本进行建模型&#xff0c;留小部分样本用刚建立的模型进行预报&#xff0c;并求这小部分样本的预…

自己手写一个字符串【C风格】

//字符串的常见操作 #include <iostream>#define MAX_SIZE 15 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status;//状态类型 typedef char ElemType;//元素类型typedef ElemType String[MAX_SIZE 1];//第一个字节记录长度//***tring是数…

华为设备WLAN配置之AP上线

WLAN基础配置之AP上线 配置WLAN无线网络的第一阶段&#xff0c;AP上线技术&#xff1a; 实验目标&#xff1a;使得AP能够获得来自AC的DHCP地址服务的地址&#xff0c;且是该网段地址池中的IP。 实验步骤&#xff1a; 1.把AC当作三层交换机配置虚拟网关 sys Enter system view,…

2024年艺术鉴赏与文化传播国际会议(AACC 2024)

2024年艺术鉴赏与文化传播国际会议&#xff08;AACC 2024&#xff09; 2024 International Conference on Art Appreciation and Cultural Communication 【重要信息】 大会地点&#xff1a;贵阳 大会官网&#xff1a;http://www.icaacc.com 投稿邮箱&#xff1a;icaaccsub-co…

webpack5零基础入门-16封装cssloader函数

1.背景 我们发现配的cssloader中有很多重复性代码&#xff0c;所以应该对其进行封装&#xff0c;减少冗余的代码 2.定义函数getCssLoader function getCssLoader(pre) {return [MiniCssExtractPlugin.loader, css-loader,{loader: postcss-loader,options: {postcssOptions:…

【笔记】树(Tree)

一、树的基本概念 1、树的简介 之前我们都是在谈论一对一的线性数据结构&#xff0c;可现实中也有很多一对多的情况需要处理&#xff0c;所以我们就需要一种能实现一对多的数据结构--“树”。 2、树的定义 树&#xff08;Tree&#xff09;是一种非线性的数据结构&#xff0…

Excel/WPS《超级处理器》同类项处理,合并同类项与拆分同类项目

在工作中处理表格数据&#xff0c;经常会遇到同类项处理的问题&#xff0c;合并同类项或者拆分同类项&#xff0c;接下来介绍使用超级处理器工具如何完成。 合并同类项 将同一列中的相同内容合并为一个单元格。 1&#xff09;用分隔符号隔开 将AB列表格&#xff0c;合并后为…

UML中的图-13中UML图详解

图是一组元素的图形表示&#xff0c;大多数情况下把图画成顶点和弧的联通图。 UML提供了13种图&#xff0c;分别是类图、对象图、用例图、序列图、通信图、状态图、活动图、构建图、组合结构图、部署图、包图、交互概览图和计时图。序列图、通信图、交互概览图和计时图均被称为…

vue3的核心API功能:computed()API使用

常规使用方法: 这样是常规使用方法. 另一种使用方法: 这样分别定义computed的get回调函数和set回调函数, 上面例子定义了plusOne.value的值为1, 那么这时候就走了computed的set回调函数,而没有走get回调函数. 当我们打印plusOne.value的值的时候,走的是get的回调函数而不是…

ubuntu20.04 10分钟搭建无延迟大疆无人机多线程流媒体服务器

1.使用效果 无人机画面 2.服务器视频端口 3.使用教程 3.1.下载ubuntu对应软件包&#xff1a;系统要求ubuntu16以上 3.2修改端口&#xff08;config.xml文件&#xff09; 3.3启动服务 目录下输入&#xff1a;终端启动&#xff1a;./smart_rtmpd 后台启动&#xff1a;nohup ./…

大语言模型的工程技巧(一)——GPU计算

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch07_autograd/gpu.ipynb 本文将讨论如何利用PyTorch实现GPU计算。本…

dubbo复习: (6)和springboot集成时的条件路由

根据指定的条件&#xff0c;对不满足条件的请求进行拦截。 比如拦截ip地址为192.168.31.227的请求。只需要在dubbo admin中的条件路由菜单创建相应的规则 enabled: true force: true runtime: true conditions:- host ! 192.168.31.227

单例模式介绍,及其应用场景?

单例模式(Singleton Pattern)是 Java中最简单的设计模式之一,此模式保证某个类在运行期间,只有一个实例对外提供服务&#xff0c;而这个类被称为单例类。 单例模式也比较好理解&#xff0c;比如一个人一生当中只能有一个真实的身份证号&#xff0c;一个国家只有一个政府&#x…

【linux】深入了解线程池:基本概念与代码实例(C++)

文章目录 1. 前言1.1 概念1.2 应用场景1.3 线程池的种类1.4 线程池的通常组成 2. 代码示例2.1 log.hpp2.2 lockGuard.hpp① pthread_mutex_t 2.3 Task.hpp2.4 thread.hpp2.5 threadPool.hpp① 基本框架② 成员变量③ 构造函数④ 其余功能函数&#xff1a; main.cc结果演示 完整…

[Redis]常见数据和内部编码

相关命令 type (key) type 命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列 表&#xff09;、hash&#xff08;哈希&#xff09;、set&#xff08;集合&#xff09;、zset&#xff08;有…

Cloneable 接口和深拷贝,浅拷贝

目录 一.Cloneable 接口 二.浅拷贝 三.深拷贝 四.comparable接口、 五.comparator接口 1.Java 中内置了一些很有用的接口 , Cloneable 就是其中之一 . Object 类中存在一个 clone 方法 , 调用这个方法可以创建一个对象的 " 拷贝 ". 2.来说说调用 clone 方法…

基于大型语言模型的游戏智能体

在人工智能领域&#xff0c;游戏代理的发展对于实现通用人工智能&#xff08;AGI&#xff09;至关重要。近年来&#xff0c;大型语言模型&#xff08;LLMs&#xff09;及其多模态版本&#xff08;MLLMs&#xff09;的进展为游戏代理的进化和能力提升提供了前所未有的机遇。这些…