每日一题——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=5
    while 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+=6
    return 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+1
    while 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)
            break
        elif i>N+6 and is_prime(i) and is_prime(i+6):
            # 如果i大于N+6,并且i和i+6都是质数,则打印i并终止循环。
            print(i)
            break
        i+=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 math

def is_prime(n):
    """使用基础优化技术检查一个数是否为质数"""
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

def sieve_of_eratosthenes(limit):
    """使用埃拉托斯特尼筛法生成所有小于等于limit的质数"""
    is_prime = [True] * (limit + 1)
    p = 2
    while (p * p <= limit):
        if (is_prime[p] == True):
            for i in range(p * p, limit + 1, p):
                is_prime[i] = False
        p += 1
    prime_list = [p for p in range(2, limit + 1) if is_prime[p]]
    return prime_list

def find_prime_pair(N):
    """寻找满足条件的质数对"""
    limit = max(N + 1000, 1000)  # 设定一个合理的初始值
    primes = set(sieve_of_eratosthenes(limit))
    
    # 检查初始N
    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.")
        return
    
    # 逐步增加N并检查
    while True:
        N += 1
        if 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. 启发式方法:基于历史数据和实际情况,灵活调整系统参数和处理策略。

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


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

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

相关文章

私有化AI搜索引擎FreeAskInternet

什么是 FreeAskInternet FreeAskInternet 是一个完全免费、私有且本地运行的搜索聚合器&#xff0c;并使用 LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统将使用 searxng 进行多引擎搜索&#xff0c;并将搜索结果合并到ChatGPT3.5 LLM 中&#xff0c;并…

⌈ 传知代码 ⌋ 基于曲率的图重新布线

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

数据库索引压力测试

本实验测试数据库在有索引和五索引内容上的查询时间随着数据量级增长的变化 测试的表结构 使用一个菜单的数据库表&#xff0c;包括菜品的ID&#xff0c;菜品名和价格 CREATE TABLE Menu (dish_id int(6) unsigned zerofill NOT NULL AUTO_INCREMENT,dish_name varchar(255)…

高通Android开关机动画踩坑简单记录

1、下面报错有可能是selinux的原因 Read-only file system 2、接着push 动画 reboot之后抓取logcat出现 &#xff0c;以下这个报错。看着像是压缩格式有问题。 3、于是重新压缩一下报错没有再出现 &#xff0c;压缩格式默认是标准&#xff0c;这里必须要改成存储格式哈 4、修改…

matlab演示地月碰撞

代码 function EarthMoonCollisionSimulation()% 初始化参数earth_radius 6371; % 地球半径&#xff0c;单位&#xff1a;公里moon_radius 1737; % 月球半径&#xff0c;单位&#xff1a;公里distance 384400; % 地月距离&#xff0c;单位&#xff1a;公里collision_tim…

Signac|成年小鼠大脑 单细胞ATAC分析(2)

引言 在本教程中&#xff0c;我们将探讨由10x Genomics公司提供的成年小鼠大脑细胞的单细胞ATAC-seq数据集。本教程中使用的所有相关文件均可在10x Genomics官方网站上获取。 本教程复现了之前在人类外周血单核细胞&#xff08;PBMC&#xff09;的Signac入门教程中执行的命令。…

【linux】进程控制——进程创建,进程退出,进程等待

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 相关文章 【Linux】进程地址空间-CSDN博客 【linux】详解linux基本指令-CSDN博客 目录 进程控制概述 创建子进程 fork函数 父子进程执行流 原理刨析 常见用法 出错原因 进程退出 概…

7-43 排列问题

排列问题 分数 10 全屏浏览 切换布局 作者 雷丽兰 单位 宜春学院 全排列问题 输出自然数1至n中n个数字的全排列&#xff08;1≤n≤9&#xff09;&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式: 一个自然数 输出格式: 由1到n中n个数字组成的…

Python魔法之旅专栏(导航)

目录 推荐阅读 1、Python筑基之旅 2、Python函数之旅 3、Python算法之旅 4、博客个人主页 首先&#xff0c;感谢老铁们一直以来对我的支持与厚爱&#xff0c;让我能坚持把Python魔法方法专栏更新完毕&#xff01; 其次&#xff0c;为了方便大家查阅&#xff0c;我将此专栏…

freertos中的链表1 - 链表的数据结构

1.概述 freertos中链表的实现在 list.c 和 list.h。旨在通过学习freertos中的链表的数据结构&#xff0c;对freertos中的链表实现有一个整体的认识。freertos使用了三个数据结构来描述链表&#xff0c;分别是&#xff1a;List_t&#xff0c; MiniListItem_t&#xff0c;ListIt…

【Linux】进程6——环境变量

1.什么是环境变量 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 比如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但是照样可以链接成功&…

Windows 10 找不到Microsoft Edge 浏览器

下载链接 了解 Microsoft Edge 手动下载浏览器 问题说明 一般来说&#xff0c;windows10系统应该是自带浏览器edge的&#xff0c;但有的电脑就是没有找到edge浏览器&#xff0c;可能系统是精简过的&#xff0c;可能是被卸载了。如下&#xff0c;控制面板确实没找到程序。 ​ …

笔记本充电出现了问题。

不知道为什么。电池充电图片一直显示的空。谁能救救我&#xff01;

C++命名空间的定义、C++命名空间的使用、C++输入输出等的介绍

文章目录 前言一、C命名空间的定义1. C命名空间产生的原因2. 作用域限定符3. C变量的访问顺序 二、C命名空间的使用1. 加命名空间名称及作用域限定符2. 使用using将命名空间中某个成员引入3. 使用using namespace 命名空间名称 引入4. 嵌套命名空间使用 三、 C输入&输出总结…

天才程序员周弈帆 | Stable Diffusion 解读(二):论文精读

本文来源公众号“天才程序员周弈帆”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Stable Diffusion 解读&#xff08;二&#xff09;&#xff1a;论文精读 【小小题外话】端午安康&#xff01; 在上一篇文章天才程序员周弈帆 …

C#操作MySQL从入门到精通(14)——汇总数据

前言 我们有时候需要对数据库查询的值进行一些处理,比如求平均值等操作,本文就是详细讲解这些用法,本文测试使用的数据库数据如下: 1、求平均值 求所有student_age 列的平均值 string sql = string.Empty; if (radioButton_AVG.Checked) {sql = “select AVG( student_…

《Vue》系列文章目录

Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以…

真北游记|三江交汇,碧海苍梧,端午去梧州吃龟苓膏

准备 t-14&#xff1a;高铁抢票&#xff08;A&#xff09; t-14&#xff1a;订行程(B)酒店&#xff08;C&#xff09; T-2&#xff1a;准备水、零食 T-1&#xff1a;物质准备&#xff1a;衣服、纸巾、毛巾、雨伞&#x1f302;、拖鞋、口罩&#x1f637;&#xff08;D&#xff0…

phpstudy的安装dvwa

phpstudy安装dvwa 1. 下载phpstudy Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 2. 搭建dvwa靶场 下载地址&#xff1a;https://github.com/ethicalhack3r/DVWA/archive/master.zip 将其放入www文件夹中 3. 修改配置文件 将\DVWA-master\config中config.inc.php…

【深度揭秘】ChatGPT如何成为智能对话的领头羊?万字详解其背后的核心技术!

最近&#xff0c;OpenAI的预训练模型ChatGPT给人工智能领域的研究人员留下了深刻的印象和启发。毫无疑问&#xff0c;它非常强大&#xff0c;与之交流十分有趣&#xff0c;还能编写代码。它在多个方面的表现远超自然语言处理研究者的预期。因此&#xff0c;我们不禁要问&#x…