[解题报告]《算法零基础100讲》(第8讲) 素数筛选

简介: [解题报告]《算法零基础100讲》(第8讲) 素数筛选

文章目录


前言


   主要知识点


       埃氏筛


   扩展知识点


       线性筛(欧拉筛)


课后习题详解


   回文素数


       思路


       结果分析



前言


今天竟然有两讲,那我就要分两篇文章了,嘿嘿嘿。


主要知识点


埃氏筛


bool f[n];
    f[0] = false;
    f[1] = false;
    memset(f , 1, n);
    for(int i = 2;i < n;i++){
        if(f[i]){
            for(long long j = (long long)i*i;j < n;j += i)   f[j] = false;
        }
    }

其实就是如果找到一个素数,则这个素数所有的倍数都是合数。从i*i开始是因为i*i之前的已经被之前的元素筛了一边,避免重复。


扩展知识点


线性筛(欧拉筛)


其实上面的代码还是有缺点,比如3*10=30,5*6 = 10。会造成重复筛选,所以欧拉筛就是基于这种去处重复的思想。让每个合数只被最小质因子筛选一次。


 

bool f[n];
    int x[n];
    f[0] = false;
    f[1] = false;
    memset(f , 1, n);
    x[0] = 0;
    for(int i = 2;i < n;i++){
        if(f[i]){
            x[++x[0]] = i;
        }
        for(int j = 1;j <= x[0] && i*x[j] < n;++j){
            f[i* x[j]] = false;
            if(i % x[j] == 0) break;
        }
    }

其中f[n]记录所有搜索到的素数,然后利用素数乘现在搜索到的元素乘来对i*i范围内元素进行筛选,这样不会造乘int类型的溢出。


课后习题详解


回文素数


204. 计数质数

https://leetcode-cn.com/problems/count-primes/


统计所有小于非负整数 n 的质数的数量。


思路


其实就是直接利用埃氏筛进行,标记为素数的时候做count就好了。


int countPrimes(int n){
    if(n == 0|| n == 1)  return 0;
    bool f[n];
    f[0] = false;
    f[1] = false;
    memset(f , 1, n);
    int cnt =0;
    for(int i = 2;i < n;i++){
        if(f[i]){
            ++cnt;
            for(long long j = (long long)i*i;j < n;j += i)   f[j] = false;
        }
    }
    return cnt;
}

结果分析

image.png



还算可以把,也不算太拉跨,尝试了欧拉筛结果时间和空间复杂度都有一定规模的上升,感觉没啥必要。欢迎大佬尝试,给个参考。


int countPrimes(int n){
    if(n == 0|| n == 1)  return 0;
    bool f[n];
    int x[n];
    f[0] = false;
    f[1] = false;
    memset(f , 1, n);
    x[0] = 0;
    int cnt =0;
    for(int i = 2;i < n;i++){
        if(f[i]){
            x[++x[0]] = i;
            ++cnt;
        }
        for(int j = 1;j <= x[0] && i*x[j] < n;++j){
            f[i* x[j]] = false;
            if(i % x[j] == 0) break;
        }
    }
    return cnt;
}


这样引入一个int数组,一个int4字节直接大了好多。然后访问int类型几次之后也会更快到达buffer的末端引起缺页,所以可能性能更差吧。

相关文章
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
64 2
|
6月前
|
算法 Java Serverless
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-444 算法训练 求和问题
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-444 算法训练 求和问题
56 1
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-439 算法训练 简单字符变换
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-439 算法训练 简单字符变换
54 1
|
6月前
|
机器学习/深度学习 数据采集 监控
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
921 0
|
1月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
72 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
3月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
45 0
|
5月前
|
算法 Serverless 数据安全/隐私保护
RSA算法中,为什么需要的是两个素数?
PrimiHub是密码学专家团队开发的开源隐私计算平台,关注数据安全、密码学等领域。RSA算法使用两个素数确保安全,因为它们的乘积易于计算,但分解困难,形成加密基础。算法涉及选择大素数、计算乘积、生成公私钥对。加密时,消息通过公钥变形;解密则需私钥,安全性依赖于大数分解问题的复杂性。
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
42 2
|
6月前
|
算法 安全
死锁相关知识点以及银行家算法(解题详细步骤)
死锁相关知识点以及银行家算法(解题详细步骤)
302 2