当前位置: 首页 > wzjs >正文

150网站建设百度推广优化师培训

150网站建设,百度推广优化师培训,青浦做网站公司,学校网站如何做使用埃拉托斯特尼筛法&#xff08;Sieve of Eratosthenes&#xff09; 的高效解法&#xff0c;时间复杂度为 O (n log log n)&#xff0c;显著优于逐个判断素数的 O (n) 复杂度&#xff1a; #include <stdio.h> #include <stdlib.h> #include <stdbool.h>in…

使用埃拉托斯特尼筛法(Sieve of Eratosthenes) 的高效解法,时间复杂度为 O (n log log n),显著优于逐个判断素数的 O (n²) 复杂度:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>int count_prime_pairs(int n) {if (n < 5) return 0; // 小于5时无孪生素数对// 创建布尔数组标记素数,初始全为true(假设都是素数)bool* is_prime = (bool*)calloc(n + 1, sizeof(bool));if (!is_prime) return -1; // 内存分配失败// 初始化:0和1不是素数,其余默认是素数for (int i = 2; i <= n; i++) is_prime[i] = true;// 埃拉托斯特尼筛法:标记非素数for (int i = 2; i * i <= n; i++) {if (is_prime[i]) {for (int j = i * i; j <= n; j += i) {is_prime[j] = false;}}}// 统计孪生素数对int count = 0;for (int p = 3; p <= n - 2; p += 2) { // 从3开始只检查奇数if (is_prime[p] && is_prime[p + 2]) {count++;}}free(is_prime); // 释放内存return count;
}int main() {int n = 10;printf("孪生素数对数量:%d\n", count_prime_pairs(n)); // 输出:2return 0;
}

核心优化点

  1. 筛法求素数

    • 一次性标记所有非素数,避免重复判断。
    • 时间复杂度 O (n log log n),接近线性时间。
  2. 内存优化

    • 使用布尔数组替代整数数组,节省空间。
    • 动态分配内存适应不同的 n 值。
  3. 奇数优化

    • 孪生素数对中,p 和 q 必须都是奇数(除了 (3,5) 外,其他偶数不可能是素数)。
    • 循环步长设为 2,跳过偶数检查。
  4. 边界处理

    • 当 n < 5 时直接返回 0,减少不必要计算。

代码核心理解

1. bool* is_prime = (bool*)calloc(n + 1, sizeof(bool)); 的语法解释

这行代码使用了 C 语言的动态内存分配函数 calloc,其作用是在程序运行时动态分配一块连续的内存空间,并初始化为 0。具体解析如下:

  • calloc 函数原型void* calloc(size_t num_elements, size_t element_size);

    • num_elements:需要分配的元素数量(这里是 n + 1,表示从 0 到 n 的所有索引)
    • element_size:每个元素的大小(这里是 sizeof(bool),通常为 1 字节)
    • 返回值:指向分配内存的指针(类型为 void*,需要强制转换为目标类型)
  • 强制类型转换 (bool*):将 void* 类型的指针转换为 bool* 类型,以便赋值给 is_prime 变量。

  • 内存初始化calloc 会自动将分配的内存全部初始化为 0(即每个 bool 值都为 false),这与 malloc 不同(malloc 分配的内存值是未定义的)。

2. 埃拉托斯特尼筛法(Sieve of Eratosthenes)的逻辑

埃拉托斯特尼筛法是一种高效的素数筛选算法,其核心思想是:从 2 开始,将每个素数的倍数标记为合数。具体步骤如下:

// 初始化:0和1不是素数,其余默认是素数
for (int i = 2; i <= n; i++) is_prime[i] = true;// 埃拉托斯特尼筛法:标记非素数
for (int i = 2; i * i <= n; i++) {if (is_prime[i]) {for (int j = i * i; j <= n; j += i) {is_prime[j] = false;}}
}

  • 初始化阶段:创建一个布尔数组 is_prime,将所有索引(2 到 n)初始化为 true,表示默认都是素数。

  • 筛选阶段

    1. 外层循环:从 2 开始遍历到 √n(因为如果一个数 n 不是素数,它一定有一个因子小于等于 √n)。
    2. 检查当前数 i:如果 is_prime[i] 仍为 true,说明 i 是素数(未被前面的步骤标记为合数)。
    3. 标记合数:将 i 的所有倍数(从 i*i 开始,因为更小的倍数已经被之前的素数标记过)标记为 false
  • 优化点

    • 从 i*i 开始:例如,当 i=5 时,直接从 25 开始标记,因为 5*2=105*3=155*4=20 已经被 2 和 3 标记过。
    • 只遍历到 √n:超过 √n 的数的倍数已经被更小的素数标记过。

3. free(is_prime); 的作用:为什么要释放内存?

在 C 语言中,使用 malloccalloc 或 realloc 动态分配的内存必须在不再使用时手动释放,否则会导致内存泄漏(Memory Leak)。具体原因如下:

  • 内存生命周期:动态分配的内存位于堆(Heap)区,不会像栈(Stack)上的局部变量那样在函数返回时自动释放。如果不手动释放,这块内存会一直被占用,直到程序结束。

  • 内存泄漏后果:反复分配内存而不释放,会导致程序占用的内存不断增长,最终耗尽系统资源,导致程序崩溃或系统变慢。

  • 正确做法

    1. 使用 calloc 分配内存。
    2. 使用完内存后(通常在不再需要该内存的地方,如函数结束前),调用 free 释放它。
    3. 将指针置为 NULL(可选),防止误操作:is_prime = NULL;
  • 类比:就像借书需要归还图书馆一样,动态分配的内存也需要归还给系统,以便其他程序或本程序的其他部分可以使用。

http://www.dtcms.com/wzjs/410358.html

相关文章:

  • apache建设网站如何制作网页链接教程
  • 乐云seo网站建设性价比高哈尔滨电话本黄页
  • 黄埔做网站的公关于华大18年专注seo服务网站制作应用开发
  • 宁夏住房和城乡建设厅网站首页百度人工电话多少号
  • 做公益网站的目的推广策略
  • asp网站上哪做杭州网站排名seo
  • 建设个人网站的要求个人博客网页设计
  • 网站连接如何做二维码合肥关键词快速排名
  • 微网站如何做微信支付宝支付接口360免费建站教程
  • 个人网站模板html代码视频号视频怎么看下载链接
  • 那个可以做棋牌网站高端网站建设哪家便宜
  • 政府网站建设工作室网络营销包括哪些
  • 一站式服务宣传语推推蛙seo顾问
  • 山东建设网站首页营销和销售的区别在哪里
  • 企业展示网站建设需要做什么游戏推广员拉人犯法吗
  • 长春专业做网站网站建设方案书模板
  • 网站商品展示页怎么做的重庆网站
  • 怎样做网站挣钱营业推广的方式
  • 上海奉贤做网站宁德市中医院
  • 网站建设华科技公司网页关键词优化软件
  • 重庆网络推广排行台州seo排名扣费
  • 长宁区建设交通委员会网站网站点击软件排名
  • 公主岭网站建设网络优化工程师骗局
  • 网店设计模板免费优化精灵
  • 预约营销型网站建设专家免费seo优化
  • 在线制作广告图片seo优化方向
  • 高负载php网站开发做公司网站
  • 做网站排名seo好的在线crm系统
  • 陕西网站建设方案南京市网站
  • 网站php怎么做新网站如何让百度收录