每日一题——Python实现PAT乙级1099 性感素数(举一反三+思想解读+逐步优化)


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

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

Python-3.12.0文档解读

目录

我的写法

专业点评

时间复杂度分析

空间复杂度分析

综合点评

我要更强

优化点

具体步骤

哲学和编程思想

1. 分而治之(Divide and Conquer)

2. 空间换时间(Space-Time Tradeoff)

3. 懒惰求值(Lazy Evaluation)

4. 优化(Optimization)

5. 渐进式复杂度分析(Asymptotic Analysis)

6. 模块化(Modularity)

7. 迭代与递增(Iterative and Incremental Development)

8. 实际应用中的启发式方法(Heuristics in Practical Applications)

举一反三

1. 分而治之(Divide and Conquer)

2. 空间换时间(Space-Time Tradeoff)

3. 懒惰求值(Lazy Evaluation)

4. 优化(Optimization)

5. 渐进式复杂度分析(Asymptotic Analysis)

6. 模块化(Modularity)

7. 迭代与递增(Iterative and Incremental Development)

8. 实际应用中的启发式方法(Heuristics in Practical Applications)

综合应用实例


 

 题目链接


我的写法

def is_prime(num):# 定义一个函数is_prime,用于检查传入的参数num是否为质数。if num<=1:return False  # 如果num小于等于1,直接返回False,因为1和负数都不是质数。if num<=3:return True  # 如果num小于等于3,则返回True,因为2和3都是质数。if num%2==0 or num%3==0:return False  # 如果num能被2或3整除,则不是质数,返回False。i=5while i*i<=num:# 使用一个while循环来检查从5开始的所有数(i的步长为6),直到i的平方大于num。if num%i==0 or num%(i+2)==0:return False  # 如果num能被i或i+2整除,则不是质数,返回False。i+=6return True  # 如果所有的检查都通过了,则num是质数,返回True。N=int(input())  # 从用户那里获取一个整数输入,并将其赋值给变量N。# 下面检查N和它的邻居(N-6或N+6)是否都是质数。
if is_prime(N-6) and is_prime(N):# 如果N-6和N都是质数,则打印"Yes"和N-6。print("Yes")print(N-6)
elif is_prime(N+6) and is_prime(N):# 如果N和N+6都是质数,则打印"Yes"和N+6。print("Yes")print(N+6)
else:# 如果上述条件都不满足,则执行下面的代码。print("No")  # 首先打印"No",表示N和它的邻居不都是质数。i=N+1while True:# 使用一个无限循环来查找距N最近的一对质数距,其中一个数为i,另一个数为i-6或i+6。if i<N+6 and (is_prime(i-6) and is_prime(i)) or (is_prime(i) and is_prime(i+6)):# 如果i小于N+6,并且i-6和i或者i和i+6都是质数,则打印i并终止循环。print(i)breakelif i>N+6 and is_prime(i) and is_prime(i+6):# 如果i大于N+6,并且i和i+6都是质数,则打印i并终止循环。print(i)breaki+=1  # 将i的值增加1,然后继续循环。

专业点评

  1. is_prime函数:
    • 优点:
      • 该函数使用了一些基础的优化技术,例如排除2和3的倍数,提高了检查质数的效率。
      • 使用了6的倍数规则(6k ± 1)来进一步减少检查次数。
    • 缺点:
    • 对于非常大的数,效率仍然有限。可以考虑使用更高级的质数测试算法,如 Miller-Rabin 质数测试。
  2. find_prime_pair函数:
  • 优点:
    • 逻辑结构清晰。先检查给定的 N 是否满足条件,然后逐步递增 N,直到找到满足条件的数。
  • 缺点:
  • 逐个增加 N 并检查,效率较低。对于较大的 N,这种方法可能会很慢。

时间复杂度分析

  1. is_prime函数:
    • 时间复杂度是 O(√n),因为最多需要检查到 n 的平方根。
  2. find_prime_pair函数:
  • 初始检查:最多调用两次 is_prime,因此时间复杂度为 O(√N)。
  • 逐步寻找:最坏情况下,需要检查多个数。假设需要检查 k 个数,每次调用 is_prime 的时间复杂度为 O(√M)(M 是正在检查的数)。因此,最坏情况下,主逻辑的时间复杂度近似为 O(k * √M),其中 k 和 M 与输入 N 相关。实际复杂度可能更低,但仍在多项式时间内。

空间复杂度分析

  1. is_prime函数:
    • 空间复杂度是 O(1),只使用了常数级别的额外空间(几个变量)。
  2. find_prime_pair函数:
  • 空间复杂度是 O(1),除了输入和几个常数级别的变量外,没有使用额外的空间。

综合点评

优点:

  • is_prime 函数通过基础优化减少了计算量,提升了性能。
  • find_prime_pair 函数逻辑结构清晰,能够有效判断并找到质数对。

改进建议:

  • 当 N 很大时,逐个递增检查的效率较低,可以考虑使用更高效的质数生成算法,如埃拉托斯特尼筛法,提前生成一段范围内的质数以供查找。
  • is_prime 函数可以进一步优化,比如使用 Miller-Rabin 质数测试来提升大数的质数检查效率。
  • 添加更多注释和代码格式化,以提高代码的可读性。

总体而言,这段代码在功能上是正确的,并且进行了基本的优化,但在处理大数时可以通过更高级的算法进一步提升性能。


我要更强

为了优化时间复杂度和空间复杂度,我们可以采取以下措施:

  1. 使用埃拉托斯特尼筛法预生成质数:这可以显著加快质数的判定。
  2. 使用更高效的质数测试算法:如 Miller-Rabin 质数测试。
  3. 提前生成一段范围内的质数对:避免逐个递增检查。

下面提供一个优化后的代码,包含详细注释:

import mathdef is_prime(n):"""使用基础优化技术检查一个数是否为质数"""if n <= 1:return Falseif n <= 3:return Trueif n % 2 == 0 or n % 3 == 0:return Falsei = 5while i * i <= n:if n % i == 0 or n % (i + 2) == 0:return Falsei += 6return Truedef sieve_of_eratosthenes(limit):"""使用埃拉托斯特尼筛法生成所有小于等于limit的质数"""is_prime = [True] * (limit + 1)p = 2while (p * p <= limit):if (is_prime[p] == True):for i in range(p * p, limit + 1, p):is_prime[i] = Falsep += 1prime_list = [p for p in range(2, limit + 1) if is_prime[p]]return prime_listdef find_prime_pair(N):"""寻找满足条件的质数对"""limit = max(N + 1000, 1000)  # 设定一个合理的初始值primes = set(sieve_of_eratosthenes(limit))# 检查初始Nif N in primes and ((N - 6) in primes or (N + 6) in primes):print(f"{N} is part of a prime pair with a difference of 6.")return# 逐步增加N并检查while True:N += 1if N > limit:limit *= 2  # 扩展筛选范围primes.update(sieve_of_eratosthenes(limit))if N in primes and ((N - 6) in primes or (N + 6) in primes):print(f"{N} is part of a prime pair with a difference of 6.")break# 示例调用
find_prime_pair(20)

优化点

  1. 埃拉托斯特尼筛法:
    • 时间复杂度:生成所有小于等于 limit 的质数的时间复杂度是 �(�log⁡(log⁡(�)))O(nlog(log(n))),其中 n 是 limit 的值。
    • 空间复杂度:存储质数的空间复杂度是 �(�)O(n)。
  2. 动态扩展筛选范围:
    • 通过逐步扩展筛选范围(即当 N 超过当前 limit 时,将 limit 翻倍),避免了一开始设置过大的范围,从而节省空间和时间。
  3. 使用集合:
  • 将质数存储在集合中,可以实现快速查找,查找操作的时间复杂度为 �(1)O(1)。

具体步骤

  1. 初始化筛选范围:
    • 使用埃拉托斯特尼筛法生成 N + 1000 或 1000 范围内的质数,取二者中的最大值作为初始筛选范围。
  2. 初始检查:
    • 检查 N 是否为质数,并检查 N-6 或 N+6 是否为质数。
  3. 逐步增加 N 并检查:
  • 如果 N 超过当前筛选范围,则扩展筛选范围并重新生成质数列表。
  • 检查新的 N 是否为质数,并检查 N-6 或 N+6 是否为质数。

通过这些优化,可以显著提升代码的运行效率,特别是在处理较大数范围时。


哲学和编程思想

在优化代码的过程中,多个哲学和编程思想被应用。这些思想不仅提高了代码的效率,还增强了代码的可维护性和可读性。以下是具体的方法及其背后的哲学和编程思想:

1. 分而治之(Divide and Conquer)

应用:埃拉托斯特尼筛法和动态扩展筛选范围。

哲学与编程思想: 分而治之是一种将一个复杂问题分解为多个更小、更易解决的问题,然后分别解决这些小问题,再将其合并以得到最终解决方案的方法。在埃拉托斯特尼筛法中,我们将质数判定拆解为多个小范围内的判定,通过逐步扩展筛选范围来解决整个问题。

2. 空间换时间(Space-Time Tradeoff)

应用:使用集合存储质数以实现快速查找。

哲学与编程思想: 空间换时间是计算机科学中的一种常见策略,即通过使用更多的存储空间来提高运行速度。在我们的代码中,使用集合存储质数可以在常数时间内(O(1))完成查找操作,从而显著提高效率。

3. 懒惰求值(Lazy Evaluation)

应用:动态扩展筛选范围而不是一次性生成一个极大的质数范围。

哲学与编程思想: 懒惰求值是一种只在需要时才进行计算的策略。通过动态扩展筛选范围,我们避免一次性生成大量数据,从而节省了初始计算时间和空间。这种方法使程序在处理较小输入时更加高效,同时仍能处理较大输入。

4. 优化(Optimization)

应用:基础的质数判定算法优化。

哲学与编程思想: 优化是通过改进算法和数据结构以提高程序效率的过程。在质数判定中,通过排除2和3的倍数以及使用6k ± 1规则,我们减少了不必要的计算,从而提高了算法效率。

5. 渐进式复杂度分析(Asymptotic Analysis)

应用:对算法的时间复杂度和空间复杂度进行分析和优化。

哲学与编程思想: 渐进式复杂度分析是评估算法在输入规模趋近无穷大时的性能表现的方法。通过分析和优化时间复杂度和空间复杂度,我们确保代码在处理大规模输入时仍然高效。

6. 模块化(Modularity)

应用:将质数判定和质数对查找分成独立的函数。

哲学与编程思想: 模块化是将程序划分为独立、可重用模块的方法。通过将质数判定和质数对查找分成独立的函数,我们提高了代码的可读性、可维护性和可测试性。

7. 迭代与递增(Iterative and Incremental Development)

应用:逐步增加N并检查质数对。

哲学与编程思想: 迭代与递增是一种开发和优化方法,通过逐步改进和扩展解决方案来最终解决问题。在逐步增加N并检查质数对的过程中,我们应用了这一思想,通过不断迭代来找到满足条件的质数对。

8. 实际应用中的启发式方法(Heuristics in Practical Applications)

应用:初始设置范围,并基于实际情况动态调整。

哲学与编程思想: 启发式方法是基于经验和直觉来快速找到可接受解决方案的方法。在代码中,我们设置了初始筛选范围,并根据实际情况动态调整,这是一种启发式方法,确保在大多数情况下性能表现良好。

通过应用这些哲学和编程思想,不仅提升了程序的效率,还提高了代码的清晰度和可维护性。这些思想在编程中的实际应用,帮助以更系统化和高效的方式解决复杂问题。


举一反三

可以通过以下一些技巧来应用上述哲学和编程思想,从而举一反三,解决更多类似的问题:

1. 分而治之(Divide and Conquer)

技巧

  • 划分问题:将一个大问题分割成多个独立的小问题。思考如何将复杂问题拆解为更简单的子问题。
  • 递归思维:使用递归方法解决分治问题,确保每个子问题都有明确的解。
  • 合并结果:在解决所有子问题后,合并结果形成最终解决方案。

应用实例

  • 排序算法(如快速排序、归并排序)。
  • 二分查找。

2. 空间换时间(Space-Time Tradeoff)

技巧

  • 缓存结果:使用缓存(如哈希表、数组)存储已计算的结果,避免重复计算(动态规划)。
  • 预计算:在需要时预计算一些结果,存储起来以供后续快速查找。

应用实例

  • 动态规划中的备忘录技术。
  • 数据库索引。

3. 懒惰求值(Lazy Evaluation)

技巧

  • 延迟计算:仅当确实需要某个值时才进行计算,避免不必要的计算开销。
  • 生成器:使用生成器在需要时生成数据,避免一次性生成大量数据。

应用实例

  • Python中的生成器和迭代器。
  • 惰性求值数据结构(如Haskell中的列表)。

4. 优化(Optimization)

技巧

  • 算法改进:从时间和空间两个方面考虑,选择更高效的算法。
  • 数据结构选择:根据具体需求选择最合适的数据结构(如哈希表、堆、树等)。

应用实例

  • 从O(n^2)改进为O(n log n)的排序算法。
  • 使用哈希表快速查找元素。

5. 渐进式复杂度分析(Asymptotic Analysis)

技巧

  • 大O符号:掌握并应用大O符号,分析算法的时间和空间复杂度。
  • 分阶段优化:首先确保算法能够工作,然后逐步优化其性能。

应用实例

  • 评估算法的最坏情况、平均情况和最佳情况复杂度。
  • 选择不同输入规模下的最优算法。

6. 模块化(Modularity)

技巧

  • 功能分解:将复杂功能分解为多个独立、可重用的模块。
  • 接口设计:设计清晰的接口,使模块之间的依赖最小化。

应用实例

  • 设计面向对象程序中的类和方法。
  • 构建微服务架构。

7. 迭代与递增(Iterative and Incremental Development)

技巧

  • 小步改进:通过小步迭代,不断改进和扩展功能。
  • 快速反馈:每次迭代后进行测试和反馈,确保方向正确。

应用实例

  • 敏捷开发方法中的迭代冲刺。
  • 原型开发。

8. 实际应用中的启发式方法(Heuristics in Practical Applications)

技巧

  • 经验积累:基于过去的经验和直觉,快速制定解决方案。
  • 灵活调整:根据实际情况动态调整策略,避免僵化。

应用实例

  • 启发式搜索算法(如A*算法)。
  • 数据分析中的特征选择和模型调整。

综合应用实例

假设你需要设计一个高效的数据处理系统,可以应用上述技巧如下:

  1. 分而治之:将数据处理过程分解为预处理、主处理和后处理三个阶段,每个阶段独立处理。
  2. 空间换时间:使用缓存机制,存储中间结果,避免重复计算。
  3. 懒惰求值:在主处理阶段使用生成器,逐步处理数据,避免一次性加载所有数据。
  4. 优化:选择最优的数据结构和算法,如使用堆进行优先级队列操作。
  5. 渐进式复杂度分析:分析每个处理阶段的时间和空间复杂度,确保整体复杂度在可接受范围内。
  6. 模块化:将预处理、主处理和后处理分别设计为独立模块,并定义清晰的接口。
  7. 迭代与递增:通过小步迭代,不断改进系统,增加新功能和优化性能。
  8. 启发式方法:基于历史数据和实际情况,灵活调整系统参数和处理策略。

通过这些技巧,可以将上述哲学和编程思想应用到更多实际问题中,开发出高效、灵活且可维护的解决方案。


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

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

相关文章

力扣每日一题130:被围绕的区域

题目 中等 相关标签 相关企业 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域里所有的 O 用 X 填充。 示例 1&#xff1a; 输入&#xff1a;board [["X","X","X"…

U盘文件系统结构损坏的应对与预防

在数字化时代&#xff0c;U盘作为便携式存储设备&#xff0c;其重要性不言而喻。然而&#xff0c;当U盘文件系统结构损坏时&#xff0c;我们可能会面临数据丢失的风险。本文将深入探讨U盘文件系统结构损坏的问题&#xff0c;分析其产生的原因&#xff0c;并给出相应的数据恢复方…

基于pytoch卷积神经网络水质图像分类实战

具体怎么学习pytorch&#xff0c;看b站刘二大人的视频。 完整代码&#xff1a; import numpy as np import os from PIL import Image import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data…

时序数据库是Niche Market吗?

引言 DB-Engines的流行程度排行从其评估标准[4]可以看出完全不能够做为市场规模的评估标准。甚至于在知道市场规模后可以用这个排行作为一个避雷手册。毕竟现存市场小&#xff0c;可预见增长规模小&#xff0c;竞争大&#xff0c;创新不足&#xff0c;那只能卷价格&#xff0c…

【文献阅读】LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

目录 1. motivation2. overall3. model3.1 low rank parametrized update matrices3.2 applying lora to transformer 4. limitation5. experiment6. 代码7. 补充参考文献 1. motivation 常规的adaptation需要的微调成本过大现有方法的不足&#xff1a; Adapter Layers Introd…

.net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript

.net core 使用js&#xff0c;.net core 使用javascript&#xff0c;在.net core项目中怎么使用javascript 我项目里需要用到“文字编码”&#xff0c;为了保证前端和后端的编码解码不处bug, 所以&#xff0c;我在项目中用了这个 下面推荐之前在.net F4.0时的方法 文章一&#…

操作系统真象还原:中断

第7章-中断 这是一个网站有所有小节的代码实现&#xff0c;同时也包含了Bochs等文件 7.2操作系统是中断驱动的 没有中断&#xff0c;操作系统几乎什么都做不了&#xff0c;操作系统是中断驱动。 7.3中断分类 7.3.1外部中断 外部中断是指来自 CPU 外部的中断&#xff0c;而…

Python基础教程(八):迭代器与生成器编程

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

时隔很久运行苍穹外卖项目,出现很多错误

中途运行了很多其他项目&#xff0c;maven的配置文件还被我修改了一次。导致再次运行苍穹外卖项目出现很多错误。 发现没有办法&#xff0c;把本地的仓库删了个干干净净。然后点击clean发现报错&#xff1a; Cannot access alimaven (http://mavejavascript:void(0);n.aliyun.…

力扣每日一题 6/10

881.救生艇[中等] 题目&#xff1a; 给定数组 people 。people[i]表示第 i 个人的体重 &#xff0c;船的数量不限&#xff0c;每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人&#xff0c;但条件是这些人的重量之和最多为 limit。 返回 承载所有人所需的最小船…

Vue15-watch对比计算属性

一、姓名案例 1-1、watch实现 1-2、计算属性 对比发现&#xff1a; 计算属性比watch属性更简略一些。 1-3、计算属性 VS 侦听属性 1-4、需求变更 计算属性中不能开启异步任务&#xff01;&#xff01;&#xff01;因为计算属性靠return返回值。但是watch靠亲自写代码去改。 1-…

streamlit:如何快速构建一个应用,不会前端也能写出好看的界面

通过本文你可以了解到&#xff1a; 如何安装streamlit&#xff0c;运行起来第一个demo熟悉streamlit的基本语法&#xff0c;常用的一些组件使用streamlit库构建应用 大模型学习参考&#xff1a; 大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业…

设计模式之观察者模式ObserverPattern(十一)

一、概述 观察者模式 (Observer Pattern) 是一种行为型设计模式&#xff0c;又被称为发布-订阅 (Publish/Subscribe) 模式&#xff0c;它定义了对象之间的一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会自动收到通知并更新…

Duck Bro的第512天创作纪念日

Tips&#xff1a;发布的文章将会展示至 里程碑专区 &#xff0c;也可以在 专区 内查看其他创作者的纪念日文章 我的创作纪念日第512天 文章目录 我的创作纪念日第512天一、与CSDN平台的相遇1. 为什么在CSDN这个平台进行创作&#xff1f;2. 创作这些文章是为了赚钱吗&#xff1f…

手写kNN算法的实现-用欧几里德空间来度量距离

kNN的算法思路&#xff1a;找K个离预测点最近的点&#xff0c;然后让它们进行投票决定预测点的类型。 step 1: kNN存储样本点的特征数据和标签数据step 2: 计算预测点到所有样本点的距离&#xff0c;关于这个距离&#xff0c;我们用欧几里德距离来度量&#xff08;其实还有很多…

ui自动化中,selenium进行元素定位,以及CSS,xpath定位总结

几种定位方式 简单代码 from selenium import webdriver import time# 创建浏览器驱动对象 from selenium.webdriver.common.by import Bydriver webdriver.Chrome() # 参数写浏览器驱动文件的路径&#xff0c;若配置到环境变量就不用写了 # 访问网址 driver.get…

WPF-UI布局

WPF布局元素有如下几个&#xff1a; Grid&#xff1a;网格。可以自定义行和列并通过行列的数量、行高和列宽来调整控件的布局。StackPanel&#xff1a;栈式面板。可将包含的元素在竖直或水平方向上排成一条直线&#xff0c;当移除一个元素后&#xff0c;后面的元素会自动向前移…

两台电脑通过网线直连共享数据(超详细)- 我的实践记录

原文链接 按照原文的操作&#xff0c;成功通过直连网线连接了两台windows电脑并共享传输数据。 ping不通可能是防火墙没关闭导致的&#xff0c;但是完全关闭防火墙又不安全。 那么有没有不关闭防火墙&#xff0c;能够上网&#xff0c;又能直连另一台电脑呢&#xff1f; 我们…

Linux启动KKfileview文件在线浏览时报错:启动office组件失败,请检查office组件是否可用

目录 1、导论 2、报错信息 3、问题分析 4、解决方法 4.1、下载 4.2、安装步骤 1、导论 今天进行项目部署时&#xff0c;遇到了一个问题。在启动kkfileview时&#xff0c;出现了报错异常&#xff1a; 2024-06-09 06:36:44.765 ERROR 1 --- [ main] cn.keking.service.Of…

全球溃败,苹果可能要全球大降价了,试图摆脱中国制造的后果

苹果一季度在中国市场的出货量暴跌&#xff0c;导致它不得不在中国市场大降价&#xff0c;从3月份就在中国市场大幅度降价&#xff0c;然而目前它在美国和欧洲两大市场也出现大幅衰退&#xff0c;降价可能将成为苹果在全球的举措。 市调机构Canalys公布的一季度数据显示&#x…