【算法学习】找素数的几种算法: 简单穷举, 埃氏筛法, 欧氏筛法, 从O(n2)到O(n)

本文详细介绍了多种寻找素数的算法,包括穷举法、优化后的布尔+break法、利用数学推导缩小除数范围的方法、埃氏筛选法及其优化、以及欧氏筛法等。每种方法均给出了具体的实现代码及时间复杂度分析。

文章简介

本文记录寻找素数的几种算法, 本文中的O()没有指明默认表示时间复杂度
代码使用Java

正文

素数/质数, 一个只可以被1和它本身整除的数, 换句话说, 不能被比他小的任意两个整数的乘积表示的数字.

打印1~n之间素数, 一直是一个入门级别的算法, 在学习编程思想的时候会出现在各种题里,
文中n取100, 打印结果都为:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

我们最开始写的可能是这样的

穷举计数法(判断O(n))

	/**
     * 打印1到n间的所有素数, 包括n.
     *
     * @param n 查找到n
     */
    static void printPrimeNumber(int n) {
   
   
        for (int i = 1; i < n + 1; i++) {
   
   
            /*这个循环遍历1~n的所有数字i*/
            /*一个被整除次数的标志位, 如果为2, 只被1和它本身整除了, 是素数, 其它>2的值就证明不是素数*/
            int divided = 0;
            for (int j = i; j >= 1; j--) {
   
   
                /*这个循环遍历1~i的所有数字, 如果能被整除, "能被整除"计数器+1 */
                if (i % j == 0) {
   
   
                    divided++;
                }
            }
            if (divided == 2) {
   
   
                /*如上所述, 该数是素数*/
                System.out.print(i + " ");
            }
        }
    }

n=1000时,一百次平均用时10.76ms

优化: 布尔+break(判断 小于O(n))

	/**
     * 打印1到n间的所有素数, 包括n.
     *
     * @param n 查找到n
     */
	static void printPrimeNumberPro(int n) {
   
   
        /*for (int i = 1; i < n+1; i++) {*/
        /* 1不是素数, 可以直接跳过*/
        for (int i = 2; i < n + 1; i++) {
   
   
            /*int divided = 0;*/
            /*本质上, 判定一个数字是不是素数, 只需要看能不能被n与1以外的数字整除就行了, 利用一个bool量, 再加上break, 不要傻傻计数*/
            boolean isPrime = true;
            /*for (int j = i - 1; j > 1; j--) {*/
            /*直觉上, 从小向大而不是从小向大遍历除数, 可以更快判定, 后面给出这点的证明*/
            for (int j = 2; j < i; j++) {
   
   
                if (i % j == 0) {
   
   
                    /*divided++*/
                    isPrime = false;
                    /*break可以减少比较次数*/
                    break;
                }
            }
            if (isPrime) {
   
   
                System.out.print(i + " ");
            }
        }
    }

n=1000时,一百次平均用时6.23ms

优化: 利用数学推导缩小除数范围(判断O( n \sqrt{n} n ))

一个数字n可以被整除时, 意味着它可以被 除数和商的乘积表示, 设除数为j, 商为k
若 : n j = k 若: \frac{n}{j}=k\\ :jn=k
此时
n = n ∗ n = j ∗ k 又 : j ≠ k \begin{aligned} n &= \sqrt{n}*\sqrt{n} \\

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

3Andman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值