一种快速判断是否为质数的方法

本文介绍了一种用于判断整数是否为素数的有效算法。该算法首先检查小于等于7的特殊情况,然后通过排除2、3、5的倍数来减少不必要的计算,并使用sqrt(x)作为循环的上限以提高效率。
  public   static   boolean  isprime( int  x)  {
    
if (x <= 7{
      
if (x == 2 || x == 3 || x==5 || x == 7)
        
return true;
    }

    
int c = 7;
    
if (x % 2 == 0)
      
return false;
    
if (x % 3 == 0)
      
return false;
    
if (x % 5 == 0)
      
return false;
    
int end = (int) Math.sqrt(x);
    
while (c <= end) {
      
if (x % c == 0{
        
return false;
      }

      c 
+= 4;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 2;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 4;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 2;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 4;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 6;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 2;
      
if (x % c == 0{
        
return false;
      }

      c 
+= 6;
    }

    
return true;
  }
 
要**快速判断一个整数是否质数**,我们需要结合数学原理和编程优化技巧。以下是几种从基础到高效的策略,适用于不同场景。 --- ### ✅ 方法一:基础优化版(适用于中等大小的整数) ```java public static boolean isPrime(int n) { if (n <= 1) return false; if (n == 2) return true; if (n % 2 == 0) return false; // 排除偶数 // 只检查奇数因子,从3到√n for (int i = 3; i * i <= n; i += 2) { if (n % i == 0) return false; } return true; } ``` #### 🔍 解释: - 时间复杂度:**O(√n)**,但跳过了所有偶数,实际运行速度接近 O(√n / 2) - 空间复杂度:O(1) - 适合判断单个数是否质数(如 n < 10^9) --- ### ✅ 方法二:预处理 + 埃拉托斯特尼筛法(Sieve of Eratosthenes)——批量判断更快 如果你需要频繁判断多个数是否质数(比如 1~10000 内的所有质数),使用**筛法预处理**是最快的。 ```java import java.util.Arrays; public class SievePrimeChecker { private static boolean[] isPrime; // 预处理生成 [0, max] 范围内的质数标记数组 public static void sieve(int max) { isPrime = new boolean[max + 1]; Arrays.fill(isPrime, true); isPrime[0] = isPrime[1] = false; for (int i = 2; i * i <= max; i++) { if (isPrime[i]) { for (int j = i * i; j <= max; j += i) { isPrime[j] = false; } } } } // 快速查询 public static boolean isPrime(int n) { if (n < 0 || n >= isPrime.length) return false; return isPrime[n]; } public static void main(String[] args) { sieve(100); // 预处理 0~100 System.out.println("97 是质数吗?" + isPrime(97)); // true } } ``` #### 🔍 优势: - 预处理时间:O(n log log n) - 查询时间:**O(1)** —— 每次判断只需查表! - 适合多次查询、范围已知的情况 --- ### ✅ 方法三:米勒-拉宾素性测试(Miller-Rabin)——用于大数快速概率判断 当你要判断的是非常大的数(如 `long` 类型甚至 BigInteger),传统方法太慢,可以使用**概率性算法**:**米勒-拉宾(Miller-Rabin)** ```java import java.math.BigInteger; import java.util.Random; public class MillerRabin { private static final Random rand = new Random(); // 使用 Miller-Rabin 判断大数是否为“可能质数” public static boolean isProbablyPrime(long n, int iterations) { if (n < 2) return false; if (n == 2 || n == 3) return true; if (n % 2 == 0) return false; // 将 n-1 写成 d * 2^r 的形式 long d = n - 1; int r = 0; while (d % 2 == 0) { d /= 2; r++; } // 进行若干轮测试 for (int i = 0; i < iterations; i++) { long a = 2 + rand.nextInt((int)(n - 4)); long x = modPow(a, d, n); // 计算 a^d mod n if (x == 1 || x == n - 1) continue; boolean composite = true; for (int j = 0; j < r - 1; j++) { x = modMul(x, x, n); // x = x^2 mod n if (x == n - 1) { composite = false; break; } } if (composite) return false; } return true; } // 快速幂取模:(base^exp) % mod private static long modPow(long base, long exp, long mod) { long result = 1; base %= mod; while (exp > 0) { if (exp % 2 == 1) result = modMul(result, base, mod); base = modMul(base, base, mod); exp >>= 1; } return result; } // 快速乘取模,防止溢出 private static long modMul(long a, long b, long mod) { long res = 0; a %= mod; while (b > 0) { if (b % 2 == 1) res = (res + a) % mod; a = (a + a) % mod; b >>= 1; } return res; } public static void main(String[] args) { long n = 1000000007L; System.out.println(n + " 是质数吗?" + isProbablyPrime(n, 10)); // true } } ``` #### 🔍 特点: - 时间复杂度:**O(k log³ n)**,k 是测试轮数 - 正确率极高(可调),常用于密码学(如 RSA) - 对于 `long` 类型的大整数非常高效 --- ### 🚀 总结:如何选择最快的方法? | 场景 | 推荐方法 | 速度 | |------|----------|------| | 判断一个小整数(< 1e6) | 基础优化法 | ⚡️快 | | 多次查询某个范围内数字 | 埃拉托斯特尼筛法 | ⚡️⚡️极快(O(1) 查询) | | 判断大整数(> 1e9)或 long 型 | 米勒-拉宾 | ⚡️⚡️⚡️唯一可行方案 | ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值