每日一题——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.mzph.cn/bicheng/25734.shtml

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

相关文章

人事信息管理系统(Java+MySQL)

一、项目背景 在现代企业中&#xff0c;管理大量员工的工作信息、薪资、请假、离职等事务是一项非常繁琐和复杂的任务。传统的手工管理方式不仅效率低下&#xff0c;而且容易出错。为了提高人事管理的效率&#xff0c;减少人工操作带来的错误&#xff0c;企业迫切需要一个高效…

【JAVASE】详讲java案例(中)

这篇接着讲用java语言写程序&#xff0c;本篇文章要讲三道题&#xff1a; &#xff08;1&#xff09;数字加密 &#xff08;2&#xff09;数组拷贝 &#xff08;3&#xff09;打印乘法表 一&#xff1a;数字加密 需求&#xff1a;某系统的数字密码是一个四位数&#xff0c…

【Leetcode】881. 救生艇

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 点击打开题目链接&#x1f517; 给定数组 p e o p l e people people 。 p e o p l e [ i ] people[i] people[i]表示第 i i i 个人的体重 &#xff0c;船的数量不限&#xff0c;每艘船可以承载的最大重…

【李宏毅-生成式 AI】Spring 2024, HW5:LLM Fine-tuning 实验记录

文章目录 1. Task Overview2. Overall Workflow3. Dataset 介绍4. 代码介绍4.1 环境介绍4.2 下载 dataset4.3 下载并加载模型4.2 Notebook 代码1&#xff09;import 部分2&#xff09;固定 seed3&#xff09;加载 LLM4&#xff09;加载 tokenizer5&#xff09;设置解码参数6&am…

tcp协议的延迟应答(介绍+原则),拥塞控制(拥塞窗口,网络出现拥塞时,滑动窗口的大小如何确定,慢启动,阈值)

目录 延迟应答 引入 介绍 原则 拥塞控制 引入 网络出现拥塞 引入 介绍 介绍 拥塞窗口 介绍 决定滑动窗口的大小 慢启动 介绍 为什么要有慢启动 阈值 算法 总结 延迟应答 引入 发送方一次发送更多的数据,发送效率就越高 因为要写入网卡硬件的io速度很慢,尽量…

conda 创建环境失败

conda create -n pylableimg python3.10在conda &#xff08;base&#xff09;环境下&#xff0c;创建新的环境&#xff0c;失败。 报错&#xff1a; LookupError: didn’t find info-scipy-1.11.3-py310h309d312_0 component in C:\Users\Jane.conda\pkgs\scipy-1.11.3-py310h…

英伟达:史上最牛一笔天使投资

200万美元的天使投资&#xff0c;让刚成立就面临倒闭风险的英伟达由危转安&#xff0c;并由此缔造了一个2.8万亿美元的市值神话。 这是全球风投史上浓墨重彩的一笔。 前不久&#xff0c;黄仁勋在母校斯坦福大学的演讲中&#xff0c;提到了人生中的第一笔融资——1993年&#x…

刷代码随想录有感(98):动态规划——爬楼梯

题干&#xff1a; 代码&#xff1a; class Solution { public:int climbStairs(int n) {if(n 1)return 1;if(n 2)return 2;vector<int>dp(n 1);dp[0] 0;dp[1] 1;dp[2] 2;for(int i 3; i < n; i){dp[i] dp[i - 1] dp[i - 2];}return dp[n];} }; 其实就是斐波…

liquibase做数据库版本管理

通过这个配置就会自动启动liquibase 比对 https://www.cnblogs.com/ludangxin/p/16676701.html https://zhuyizhuo.github.io/2020/07/04/spring-boot/spring-boot-liquibase-database-version-control/

上市公司短视主义数据集(2001-2022年)

数据简介&#xff1a;上市公司短视主义是指公司管理层过于关注短期业绩和股价表现&#xff0c;而忽视公司的长期发展和战略规划。这种短视行为可能会导致公司投资决策的失误&#xff0c;影响公司的长期竞争力。 在上市公司年度报告年度中&#xff0c;通过已有的反映管理者“短…

Excel 将同一分类下的值依次填进分类格右边的格中

表格的第2列是分类&#xff0c;第3列是明细&#xff1a; ABC1S.noAccountProduct21AAAQatAAG32BAAQbIAAW43BAAQkJAAW54CAAQaAAP65DAAQaAAX76DAAQbAAX87DAAQcAAX 需要将同一分类下的值依次填入分类格右边的格中&#xff1a; ABCD1S.noAccountProduct21AAAQatAAG32BAAQbIAAWkJ…

快速安装Windows和Ubuntu双系统

一、参考资料 用UltraISO制作Ubuntu16.04 U盘启动盘 DiskPart Command-Line Options 二、相关介绍 1. MBR和GPT分区模式 MBR分区模式 MBR最大仅支持2TB磁盘&#xff0c;超过2TB不可识别。 MBR&#xff08;Master Boot Record&#xff09;&#xff0c;即硬盘的主引导记录分…

【激光雷达】

激光雷达 机械式360扫描雷达半固态激光雷达二维扫描一维扫描 固态激光雷达OPA固态激光雷达&#xff08; 光学相控阵技术&#xff09; FMCW 激光雷达 激光雷达技术在近几年可以说是蓬勃发展&#xff0c;新能源汽车的大量使用&#xff0c;给雷达技术的发展提供了肥沃的土壤&#…

嵌入式作业6

1、利用SysTick定时器编写倒计时程序&#xff0c;如初始设置为2分30秒&#xff0c;每秒在屏幕上输出一次时间&#xff0c;倒计时为0后&#xff0c;红灯亮&#xff0c;停止屏幕输出&#xff0c;并关闭SysTick定时器的中断。 2、利用RTC显示日期&#xff08;年月日、时分秒&…

【C++类和对象中篇】(构造函数和析构函数)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f369;1.默认成员函数的概念&#xff1a; &#x1f369;2.构造函数&#xff1a; 2.1特性&…

从零开始理解AdaBoost算法:设计思路与算法流程(二)【权值更新与加权表决、数学公式】

设计思路 AdaBoost算法属于Boosting算法家族中的一种&#xff0c;其基本思路是将多个弱分类器组合成一个强分类器。 “强分类器”是指一个分类准确率较高的模型“弱分类器”则是指分类准确率略高于随机猜测的简单模型。 AdaBoost的核心思想是通过 加权 的方式逐步提高分类器…

黑马es学习

es 0. 基础概念0.1 倒排索引0.2 文档、索引0.3 与mysql对比 1 基本操作1.1 mapping 索引库操作1.2 单个文档CRUD 3. DSL查询3.1 查询所有3.2 全文检索3.3 精确查询3.4 复合查询-相关性得分3.5 分页3.6 高亮3.7 总结 2. RestClientmysql与es数据同步es集群去重 黑马视频 官方使…

Docker:利用Docker搭建一个nginx服务

文章目录 搭建一个nginx服务认识nginx服务Web服务器反向代理服务器高性能特点 安装nginx启动nginx停止nginx查找nginx镜像拉取nginx镜像&#xff0c;启动nginx站点其他方式拉取nginx镜像信息通过 DIGEST 拉取镜像 搭建一个nginx服务 首先先认识一下nginx服务&#xff1a; NGI…

04-认识微服务-SpringCloud

04-认识微服务-SpringCloud 1.SpringCloud&#xff1a; 1.SpringCloud是目前国内使用最广泛的微服务框架。官网地址&#xff1a;https://spring.io/projects/spring-cloud 2.SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&…

SpringCloud-面试篇(二十四)

&#xff08;1&#xff09;Nacos如何支撑数十万服务注册的压力 小型企业来讲nacos压力没有那么大&#xff0c;但是想阿里&#xff0c;服务的数量可能会达到数万&#xff0c;那麽多的服务。当服务原来越多时&#xff0c;除了服务注册以外&#xff0c;还有服务的定时更新&#x…