2020-09-20:如何判断一个数是质数?
福哥答案2020-09-20:#福大大架构师每日一题#
1.试除法。朴素素数筛,埃氏筛,欧拉筛和区间筛。代码采用朴素素数筛。
2.费尔马素性测试法法。费马小定理:假如p是质数,a是整数,且a、p互质,那么a的(p-1)次方除以p的余数恒等于1,即:a^(p-1)≡1(mod p)。
3.米勒拉宾素性检验法。二次探测定理:如果p是一个素数,0<x<p,则方程x^2≡1(mod p)的解为x=1或x=p-1。
4.综合法。试除法+米勒拉宾素性检验。
5.AKS算法。暂时无代码。
因为用到了大整数,所以用python语言编写。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | # -*-coding:utf-8-*- import math import time from functools import wraps def quick_power(a, b, p): """ 求快速幂。ret = a^b%p。 Args: a: 底数。大于等于0并且是整数。 b: 指数。大于等于0并且是整数。 p: 模数。大于0并且是整数。 Returns: 返回结果。 Raises: IOError: 无错误。 """ a = a % p ans = 1 while b ! = 0 : if b & 1 : ans = (ans * a) % p b >> = 1 a = (a * a) % p return ans def timefn(fn): """计算性能的修饰器""" @wraps (fn) def measure_time( * args, * * kwargs): t1 = time.time() result = fn( * args, * * kwargs) t2 = time.time() print (f "@timefn: {fn.__name__} took {t2 - t1: .5f} s" ) return result return measure_time @timefn def is_prime_trial_division(num): """ 判断是否是素数。试除法。 Args: num: 大于等于2并且是整数。 Returns: 返回结果。true为素数;false是非素数。 Raises: IOError: 无错误。 """ if num < = 1 : return False if num = = 2 or num = = 3 or num = = 5 or num = = 7 : return True if num % 2 = = 0 : return False i = 3 while num % i ! = 0 : if i * i > = num: return True i = i + 2 return False @timefn def is_prime_fermat(num): """ 判断是否是素数。费尔马素性测试法(Fermat primality test) 可能会把合数误判为质数。 Args: num: 大于等于2并且是整数。 Returns: 返回结果。true为素数;false是非素数。 Raises: IOError: 无错误。 """ if num < = 1 : return False if num = = 2 or num = = 3 or num = = 5 or num = = 7 : return True if num % 2 = = 0 : return False a = 2 # a是[2,num-1]之间的随机数 if quick_power(a, num - 1 , num) = = 1 : return True else : return False # 米勒-拉宾素性检验是一种概率算法,但是,Jim Sinclair发现了一组数:2, 325, 9375, 28178, 450775, 9780504, 1795265022。用它们做 [公式] , [公式] 以内不会出错,我们使用这组数,就不用担心运气太差了。 @timefn def is_prime_miller_rabin(num): """ 判断是否是素数。米勒拉宾素性检验是一种概率算法 可能会把合数误判为质数。 Args: num: 大于等于2并且是整数。 Returns: 返回结果。true为素数;false是非素数。 Raises: IOError: 无错误。 """ # num=(2^s)*t a = 2 # 2, 325, 9375, 28178, 450775, 9780504, 1795265022 s = 0 t = num - 1 num_1 = t if not (num % 2 ): return False while not (t & 1 ): t >> = 1 s + = 1 k = quick_power(a, t, num) if k = = 1 : return True j = 0 while j < s: if k = = num_1: return True j + = 1 k = k * k % num return False @timefn def is_prime_comprehensive(num): """ 判断是否是素数。综合算法:试除法+米勒拉宾素性检验 可能会把合数误判为质数。 Args: num: 大于等于2并且是整数。 Returns: 返回结果。true为素数;false是非素数。 Raises: IOError: 无错误。 """ if num < = 1 : return False if num & 1 = = 0 : return False # 100以内的质数表 primeList = [ 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 , 53 , 59 , 61 , 67 , 71 , 73 , 79 , 83 , 89 , 97 ] # 质数表是否能整除 for prime in primeList: if num = = prime: return True if num % prime: if prime * prime > = num: return True else : return False # 米勒拉宾素性检验 return is_prime_miller_rabin(num) if __name__ = = "__main__" : print (is_prime_trial_division( 12319 ), "试除法" ) print ( "----------------------" ) print (is_prime_trial_division( 561 ), "试除法" ) print ( "----------------------" ) num = 1111111111111111111 # 质数 num = 561 # 合数 num = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F # 质数 num = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # 质数 num = 2 * * 10000 + 111 # 合数 print (is_prime_fermat(num), "费尔马素性测试法" ) print ( "----------------------" ) print (is_prime_miller_rabin(num), "米勒拉宾素性检验" ) print ( "----------------------" ) print (is_prime_comprehensive(num), "综合法" ) print ( "----------------------" ) print ( "AKS算法,暂时没代码" ) |
执行结果如下:
***
[评论](https://user.qzone.qq.com/3182319461/blog/1600556241)
公众号:福大大架构师每日一题
分类:
福大大架构师每日一题
标签:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具