C++如何判断一个数是不是素数

当然,作为一个网站的作者,我很乐意为你提供详细的攻略。

C++中判断一个数是否是素数,通常有两种方法:暴力枚举和筛法。

暴力枚举

暴力枚举是一种较为简单的方法,即对于一个数n,将n分别除以2,3,4,...,n-1,判断它是否能除尽这些数。若一旦出现n%i==0,则说明n不是素数。

暴力枚举的代码实现如下:

bool isPrime(int n) {
    if (n <= 1) return false;  // 排除小于等于1的数
    for (int i = 2; i <= n - 1; i++) {
        if (n % i == 0) return false;  // 如果 i 能够整除 n,则 n 不是素数
    }
    return true;
}

筛法

筛法则是一种更为高效的方法。常用的有埃氏筛法和线性筛法。

埃氏筛法

埃氏筛法的思路是,从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的。其具体实现流程如下:

  1. 初始化一个bool类型的数组isPrime,长度为n+1,表示每个数的状态,初始值都为true
  2. 从2开始到$\sqrt{n}$,枚举所有质数p
  3. 对于当前质数p,枚举它的倍数i,从2开始,将isPrime[ip]标记为false,即ip不是素数
  4. 注意,为了避免重复标记,i从p开始枚举

埃氏筛法的实现如下:

vector<bool> isPrime(n+1, true);  // 初始化状态

for (int i = 2; i <= sqrt(n); i++) {
    if (isPrime[i]) {
        // 将质数的倍数标记成false
        for (int j = i*i; j <= n; j += i) {
            isPrime[j] = false;
        }
    }
}

// 统计素数的数量
int cnt = 0;
for (int i = 2; i <= n; i++) {
    if (isPrime[i]) cnt++;
}

return cnt;

线性筛法

线性筛法是埃氏筛法的升级版,它使用一个数组prime存储所有素数,并使用一个bool类型的数组isPrime表示每个数的状态,初始值都为true。具体实现流程如下:

  1. 初始化一个空的数组prime,表示所有质数; 初始化一个bool类型的数组isPrime,长度为n+1,表示每个数的状态,初始值都为true
  2. 从2开始到n,枚举所有数i
  3. 如果i是质数,将它添加到数组prime中;同时,将i的倍数标记为合数,并设置isPrime[i*p]=false
  4. 如果i不是质数,枚举prime数组中所有不超过i/p的素数p,如果i%p==0,则说明i不是素数,退出循环

线性筛法的实现如下:

vector<int> prime;  // 存储素数
vector<bool> isPrime(n+1, true);  // 初始化状态

for (int i = 2; i <= n; i++) {
    if (isPrime[i]) {
        prime.push_back(i);
    }
    for (int j = 0; j < prime.size() && i*prime[j] <= n; j++) {
        isPrime[i*prime[j]] = false;
        if (i % prime[j] == 0) {
            break;
        }
    }
}

// 统计素数的数量
int cnt = 0;
for (int i = 2; i <= n; i++) {
    if (isPrime[i]) cnt++;
}

return cnt;

至此,我们已经讲解了C++如何判断一个数是不是素数的完整攻略。其中,我们分别介绍了暴力枚举、埃氏筛法和线性筛法三种方法,其中埃氏筛法和线性筛法比暴力枚举更加高效,可以在处理大量数据时发挥更大的优势。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++如何判断一个数是不是素数 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 替换json对象中的key最佳方案

    为了替换JSON对象中的key,我们可以尝试使用以下方法: 遍历对象并创建新的对象 我们可以遍历JSON对象,对每个键值对进行检查,然后创建一个新的对象来替换旧的对象中的Key。例如在JavaScript中: const oldObj = {"oldKey": "value"}; const newObj = {}; …

    C 2023年5月23日
    00
  • 全面了解java中的异常处理

    全面了解Java中的异常处理 Java中的异常处理是一种机制,可以让我们在程序中捕获并处理可能会出现的异常。在Java中,异常分为受检异常和非受检异常。受检异常必须在代码中显式处理,而非受检异常则不需要。Java中还提供了一组异常处理机制,包括try-catch-finally语句、throws语句和finally语句等。 受检异常和非受检异常 Java中的…

    C 2023年5月23日
    00
  • C++实现LeetCode(121.买卖股票的最佳时间)

    C++实现LeetCode(121.买卖股票的最佳时间) 题目描述 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。 注意:你不能在买入股票前卖出股票。 示例 1: 输入: [7,1,5,3,6,4] 输出: 5 解释: 在第2天(股票价格 =…

    C 2023年5月23日
    00
  • C语言实现设备管理系统

    C语言实现设备管理系统 1. 设备管理系统需求分析 管理员可以添加设备信息 管理员可以删除设备信息 管理员可以修改设备信息 系统可以显示设备信息 2. 设备管理系统设计 2.1 设备信息结构体 typedef struct device { int id; char name[20]; char type[20]; int quantity; float p…

    C 2023年5月23日
    00
  • C语言超详细解析函数栈帧

    C语言超详细解析函数栈帧 什么是函数栈帧? 函数栈帧指的是函数在调用时所创建的一段内存区域,用于保存函数的局部变量、参数值、返回地址等信息。在函数调用完成后,这段内存区域将被销毁。 函数栈帧包含以下信息: 函数的返回地址 函数调用时的堆栈指针ESP 函数的局部变量 函数的参数 函数栈帧的组成包含以下部分: +————————-…

    C 2023年5月23日
    00
  • C++中构造函数与析构函数的详解及其作用介绍

    C++中构造函数与析构函数的详解及其作用介绍 什么是构造函数和析构函数 在C++中,构造函数和析构函数是一种特殊类型的函数,它们通常与类相关联。构造函数在对象创建时自动调用,而析构函数在对象销毁时自动调用。构造函数用于初始化对象的数据成员,而析构函数用于释放对象分配的内存和资源。 构造函数 构造函数的作用是是在对象创建时初始化对象的数据成员;并且构造函数名称…

    C 2023年5月23日
    00
  • 浅析C++内存布局

    浅析C++内存布局 C++是一门面向过程的编程语言,与其他编程语言一样,C++也有自己的内存布局。 内存布局基本概念 堆 使用new或malloc操作后存放动态分配的数据的区域。 栈 用于存放程序运行时的函数栈帧,栈帧将在函数执行完后自行清除。 全局变量区 在程序运行前就分配好的存放全局变量的区域,该区域分为静态区和可读写区。 常量区 存放程序中常量的区域,…

    C 2023年5月22日
    00
  • 深入了解C++优先队列(priority_queue)的使用方法

    深入了解C++优先队列(priority_queue)的使用方法 什么是优先队列? 优先队列(Priority Queue)是一种数据结构,其本质是一个队列,但是队列中的元素都被赋予了优先级。优先级最高的元素最先被取出。 C++的优先队列(priority_queue)的用法 在C++中,优先队列(priority_queue)类定义在头文件中,其基本用法如…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部