输出100000以内的素数

 

#include <fstream.h>
#define N  100000
int sieve[N + 1];
void main()
{
 for(int i = 2; i <= N; i++) sieve[i] = 1;
 for(i = 2; i <= N / 2; i++) sieve[i * 2] = 0; 
 int p = 2;
 while(p * p <= N)
 {
  p = p + 1;
  while(sieve[p] == 0)
   p++;
  int t = p * p;
  int s = 2 * p;
  while(t <= N)
  {
   sieve[t] = 0;
   t = t + s;
  }
 }
 ofstream outfile("s.txt",ios::out);
 for(i = 2; i <= N; i++)
  if(sieve[i] != 0) outfile<<i<<",";  
}

 

[转]http://www.cppblog.com/percyph/archive/2009/05/14/82963.html

质数的定义

一个数,如果只有1和它本身两个因数,这样的数叫做质数,又称素数。

在上文 《素数算法大全,及C程序实现优化详解 (一) 试除法》中我们已经探讨了求解素数的一类算法,并且将试除法从最初的低效版本优化的高效的V2。那么,还有没有其它更佳算法呢?这就是下面三藏要和大家探讨的内容

合数过滤筛选法

算法描述:我们知道,素数N不能被2~(N-1)间的任何数整除;反过来看,只要能被2~(N-1)间的任何数整除的N,都不是素数。所以我们可以采用一个简单的排除法:就是对N以内的所有数,只要逐个去除值为2~(N-1)的倍数的数,剩下的就是素数。

C语言实现

// 合数过滤筛选法 Ver1 
// 参数:n 求解n以内(包括n)的素数
// 返回值:n以内素数个数 
int CompositeNumFilterV1(int n)
{
 int i, j;
 // 素数数量统计 
 int count = 0;
 // 分配素数标记空间,结合后文思考为何+1
 char* flag = (char*)malloc( n+1 ); 
 
 // 初始化素数标记 
 for (i=2; i<=n; i++)
 {
  // 为什么*(p+i)要写成flag[i]呢?可读性更佳尔 
  flag[i] = 1;
 }
 
 // 写程序要注意排版和留空,方便阅读,也可减少出错几率
 // 以2~(N-1)为因子过滤合数 
 for (i=2; i < n; i++)
 {
  for (j=2; i*j <= n; j++)
  {
   // i*j是由i,j两整数相乘而得,显然不是素数
   flag[i*j] = 0;
  }
 }
 
 // 统计素数个数
 for (i=2; i<=n; i++)
 {
  // 其实if(flag)就其同样作用了,但这么写是有留言的 
  // 请参阅《C语言程序设计常见错误剖析及解决之道》一文 
  if (1 == flag[i]) count++;
 }
  
 // 因输出费时,且和算法核心相关不大,故略
  
 // 释放内存,别忘了传说中的内存泄漏 
 free(flag);
 
 return count;
} 

在上文给出的main函数中以不同参数调用CompositeNumFilterV1函数,得到执行结果如下:

[100000]以内素数个数:9592, 计算用时:15毫秒
[1000000]以内素数个数:78498, 计算用时:125毫秒
[5000000]以内素数个数:348513, 计算用时:2578毫秒
[10000000]以内素数个数:664579, 计算用时:6281毫秒

注:因程序是非独占性运行的,所以时间不是完全精确的,但基本能反映实情

显然,比上文中的试除法要快,而且谁都可以看到上例是一个未经优化的粗陋版本,好多地方是三藏故意采用比较低效做法,为了与后文的优化版比较,凸显优化之重要,也为了初学者记住别采用类似低效做法,下面我们开始优化之旅

优化分析

上面CompositeNumFilterV1函数存在的问题有:

  1. 在外层循环,需要一直执行到n-1吗?不要,因为n/2~n-1间的数显然不能整出n
  2. 在内层循环中重复使用i*j显然是低效的,考虑到计算机中加减运算速度比乘除快,可以考虑变乘法为加法
  3. 在循环修改flag过程中,其实有很多数会被重复计算若干次,比如6=2*3=3*2,会被重复置0,类似操作很多,所以我们得设法避免或减少flag重复置0

据上述分析,我们可将程序优化如下:

// 合数过滤筛选法 Ver2 
// 参数:n 求解n以内(包括n)的素数
// 返回值:n以内素数个数 
int CompositeNumFilterV2(int n)
{
 int i, j;
 // 素数数量统计 
 int count = 0;
 // 分配素数标记空间,明白+1原因了吧,因为浪费了一个flag[0]
 char* flag = (char*)malloc( n+1 ); 
 
 // 初始化素数标记,要高效点咯
 flag[2] = 1;
 // 注意是i<n不是上例中的i<=n了,理由自思 
 for (i=3; i<n; i++)
 {
  flag[i++] = 1;
  // 偶数自然不是素数,直接置0好了 
  flag[i] = 0;
 }
 // n为奇数 
 if (n%2 != 0)
 {
  flag[n] = 1;
 }
 
 // 从3开始filter,因为2的倍数早在初始化时代就干掉了
 // 到n/2止的理由还要说吗 
 for (i=3; i <= n/2; i++)
 {
  // i是合数,请歇着吧,因为您的工作早有您的质因子代劳了 
  if (0 == flag[i]) continue;
  
  // 从i的2倍开始过滤,变乘法为加法  
  for (j=i+i; j <= n; j+=i)
  {
   flag[j] = 0;
  }
 }
 
 // 统计素数个数
 for (i=2; i<=n; i++)
 {
  if (flag[i]) count++;
 }
  
 // 因输出费时,且和算法核心相关不大,故略
  
 // 释放内存,别忘了传说中的内存泄漏 
 free(flag);
 
 return count;
} 

再来调用CompositeNumFilterV2得到执行结果:

[100000]以内素数个数:9592, 计算用时:n太小,时间精度不够
[1000000]以内素数个数:78498, 计算用时:31毫秒
[5000000]以内素数个数:348513, 计算用时:453毫秒
[10000000]以内素数个数:664579, 计算用时:1062毫秒
[100000000]以内素数个数:5761455, 计算用时:12973毫秒

哇哇,比昨天的试除发快了好多倍,可见算法的威力,值得好好学习,别说学算法没用咯。

上例着那个计算一亿以内的素数只要约13秒,应该算不错了,今天是否可以休息了呢?No,我们要追求极限!

int CompositeNumFilterV3(int n)
{
 int i, j;
 // 素数数量统计 
 int count = 0;
 // 分配素数标记空间,明白+1原因了吧,因为浪费了一个flag[0]
 char* flag = (char*)malloc( n+1 );
 // 干嘛用的,请仔细研究下文
 int mpLen = 2*3*5*7*11*13;
 char magicPattern[mpLen];
 // 奇怪的代码,why,思考无法代劳,想! 
 for (i=0; i<mpLen; i++)
 {
  magicPattern[i++] = 1;
  magicPattern[i++] = 0;
  magicPattern[i++] = 0;
  magicPattern[i++] = 0;
  magicPattern[i++] = 1;
  magicPattern[i] = 0;
 }
 for (i=4; i<=mpLen; i+=5)
  magicPattern[i] = 0;
 for (i=6; i<=mpLen; i+=7)
  magicPattern[i] = 0;
 for (i=10; i<=mpLen; i+=11)
  magicPattern[i] = 0;
 for (i=12; i<=mpLen; i+=13)
  magicPattern[i] = 0;
 
 // 新的初始化方法,将2,3,5,7,11,13的倍数全干掉
 // 而且采用memcpy以mpLen长的magicPattern来批量处理 
 int remainder = n%mpLen;
 char* p = flag+1;
 char* pstop = p+n-remainder;
 while (p < pstop)
 {
  memcpy(p, magicPattern, mpLen);
  p += mpLen;
 }
 if (remainder > 0)
 {
  memcpy(p, magicPattern, remainder);
 }
 flag[2] = 1;
 flag[3] = 1;
 flag[5] = 1;
 flag[7] = 1;
 flag[11] = 1;
 flag[13] = 1;
 
 // 从17开始filter,因为2,3,5,7,11,13的倍数早被kill了 
 // 到n/13止的,哈哈,少了好多吧
 int stop = n/13;
 for (i=17; i <= stop; i++)
 {
  // i是合数,请歇着吧,因为您的工作早有您的质因子代劳了 
  if (0 == flag[i]) continue;
  
  // 从i的17倍开始过滤
  int step = i*2;
  for (j=i*17; j <= n; j+=step)
  {
   flag[j] = 0;
  }
 }
 
 // 统计素数个数
 for (i=2; i<=n; i++)
 {
  if (flag[i]) count++;
 }
  
 // 因输出费时,且和算法核心相关不大,故略
  
 // 释放内存,别忘了传说中的内存泄漏 
 free(flag);
 
 return count;
}

再看CompositeNumFilterV3执行结果:

[1000000]以内素数个数:78498, 计算用时:15毫秒
[5000000]以内素数个数:348513, 计算用时:203毫秒
[10000000]以内素数个数:664579, 计算用时:515毫秒
[100000000]以内素数个数:5761455, 计算用时:6421毫秒

再次优化后速度提升了又一倍左右,三藏不禁有点满足了,睡觉也!

48、住宅抵押贷款支持证券的定价、风险评估与结构化设计 本文深入探讨了住宅抵押贷款支持证券(RMBS)的定价、风险评估与结构化设计。内容涵盖提高定价准确性的方差缩减方法,如准蒙特卡罗序列的应用;分析RMBS面临的利率风险、信用风险和模型风险,并提出相应的度量与应对策略;介绍利用动态规划优化CMO分层结构以最大化发行利润的方法。同时总结了RMBS的基本类型、定价流程及市场发展趋势,为投资者和发行人提供全面的决策支持。 阅读详情

相关推荐

实战指南:如何用Kamailio+FreeSWITCH搭建高并发企业通信系统(附配置模板)

本文提供了一份实战指南,详细介绍了如何利用Kamailio与FreeSWITCH构建高并发企业通信系统。通过将Kamailio作为高性能SIP信令平面处理路由与负载均衡,FreeSWITCH作为媒体与应用平面负责通话与业务逻辑,实现信令与媒体分离的电信级架构。文章深入解析了架构设计、核心配置、集群部署与性能优化,并附有配置模板,旨在帮助企业构建可水平扩展、高可用的通信解决方案。

dell8的博客 364

求1000000以内的素数

理论依据: 任何大于等于1的数都可以表示为素数的乘积 这其实是素因式分解的唯一性定理。 若一个数n是素数,显然成立。 若n是合数,则必然可分解成大于1小于n的2个数的乘积,若均是素数,刚好得证,否则其中的合数可再分成范围更小的两个数的乘积,直到都是素数为止。所以n是合数时也成立。 综上得证。 注:0,1既不是素数也不是合数 所以不妨把从2开始的每一个结果作为除数,让下一个数来依次除以它们,如果都除不尽说明这个数就是素数了,再把它加入到素数集 import time start = time.ti

weixin_58556654的博客 864

centos-stream-9上安装nvidia驱动和cuda-toolkit

centos-stream-9上安装nvidia驱动和cuda-toolkit

qq_19072921的博客 3020

用c语言输出100到200之间的素数

    素数,就是除了1和他本身,不能被其他数整除的数字。 今天我们将用三种不同的方法来实现“输出100到200之间的素数”,请往下看:1、第一种方法就是用100到200之间的每个数字,除以2到其本身前面的那一个数字,如果此过程中出现整除的现象,则该数不是素数。如果没有整除的现象,则该数为素数输出。#include&lt;stdio.h&gt; int main() { int i=0; ...

z382196849的博客 12万+

告别手动核对!用这个ABAP报表一键导出所有物料的库存与需求清单

本文介绍了如何通过定制化ABAP报表一键导出SAP系统中所有物料的库存与需求清单,整合MD04、MB52、ME2N等多个事务码的数据,大幅提升供应链管理和生产计划效率。该报表可自动生成包含库存状态、MRP需求、采购订单等关键指标的物料全景视图,帮助企业减少手工操作错误,节省时间成本。

weixin_33725515的博客 467

安川机器人外部轴添加

本文详细介绍了如何在安川机器人本体上添加第7轴以及如何设置动作,本文以添加点焊枪为例进行讲解。

haier123888的博客 7892

100000以内素数表

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

weixin_30731287的博客 2289

SAP_SD模块更改销售订单定价简介

方式优点缺点适用场景MASS简单,无需开发不能触发重新定价逻辑修改特定字段BDC (VA02)可模拟人工操作维护复杂,速度慢少量订单批改稳定、安全需ABAP支持推荐用于批量重新定价VBOF标准重算返利仅适返利类条件返利更新通过本文,我们了解了 SAP 的[SAP_SD模块更改销售订单定价]的基本概念和应用方法。希望这些信息能帮助您在实际工作中更好地使用 SAP 系统,提高工作效率和管理水平。更多SAP文章请点击更多SAP文章更新,大家一起学习进步!!!

我小时候很黑的博客 712

【算法练习】——求10万以内的素数

1. #基础写法,效率慢 prime_number = [] n = 100000 for i in range(2, n): for j in range(2,i): if not i%j: break else: prime_number.append(i) print(prime_number)

weixin_37578866的博客 1286

QGis二次开发 —— 1、win10/win11搭建Vs2017-QGis3.40.12环境(附Vs2017环境效果,附全部问题解决方法)(附:Qt助手加入QGis接口说明文档)

QGis二次开发 —— 1、Windows10搭建Vs2017-QGis环境(附Vs2017环境效果)(附:Qt助手加入QGisA接口说明文档)

1362

prplOS组件流程梳理

本文梳理了prplOS系统中设备信息管理模块(deviceinfo-manager)的工作流程。该模块启动时通过/etc/init.d/deviceinfo-manager调用核心框架amxrt执行,主要功能包括收集设备信息、管理数据模型、初始化子系统等。系统采用ODL文件定义数据模型,通过解析器将配置文件转换为内存中的对象树。流程涉及命令行参数解析、ODL文件加载、后端模块扫描等核心步骤,最终构建出完整的数据模型供上层应用访问。整个架构体现了模块化设计思想,通过动态加载插件实现功能扩展。

四儿家的小祖宗的博客 1263

C语言 计算100000以内的素数并输出

#include <stdio.h> int main() { int i,j; for(i=2;i<100000;i++) { for(j=2;j<i;j++) { if(i%j==0) break; } if(j >= i) printf("%8d",i); } return 0; }

qq_45621293的博客 1509

HTML粉色爱心(完整代码)

HTML语言实现粉色爱心的完整代码。

AIGC 1105

用输出100000以内的质数(或素数)体会算法对程序的优化

【代码】用输出100000以内的质数(或素数)体会算法对程序的优化。

qq_20637267的博客 392

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

100000以内素数java实验结果截图_关于1000000以内的素数输出(prime number)

该楼层疑似违规已被系统折叠隐藏此楼查看此楼#include #include int isPrimeNumber (long numberToCheck){long i=0;if(numberToCheck==1){return 0;}if(numberToCheck==2){return 1;}for(i=2;i<=numberToCheck/2;i++){if(numberToChec...

weixin_35781693的博客 492

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

汇编:十万以内素数

汇编 | 十万以内素数 .MODEL SMALL ;100000以内的素数 .CODE MAIN PROC FAR .386 MOV EAX,2 NEXT: MOV ECX,EAX ;ECX记录EAX的值 MOV EBX,2 AGAIN: MOV EAX,ECX CMP EBX,EAX ;只能除1和本身,即为素数 JZ L2 MOV EDX,0 DIV EBX ;EDX是余数,EAX是商

WuZian_CSU的博客 987

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

100000以内素数java实验结果截图_编写一个 Java 程序,查找 1 ~ 100 之间的素数并将运行结果输出。...

编写一个 Java 程序,查找 1 ~ 100 之间的素数并将运行结果输出。答:public static void main(String[] args) { boolean b; for (int i = 2; i <= 100; i++) { b = true; for (int j = 2; j < i; j++) { if (i % j == 0) { b = false; ...

weixin_33312000的博客 671

1007 素数对猜想

#include<stdio.h> int main(){ int a; scanf("%d",&a); int b[9592],c=2,d=0,n=5,m; //100000以内有9592个素数 for(b[0]=2,b[1]=3;n<=a;n+=2){ for(m=0;n%b[m]&&b[m]*b[m]<n;m++); if(b[m]*b[m]>n){ .

qq_58241983的博客 118

1411:区间内的真素数

1411:区间内的真素数 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 7020 通过数: 2825 【题目描述】 找出正整数M和N之间(N不小于M)的所有真素数。 真素数的定义:如果一个正整数P为素数,且其反序也为素数,那么P就为真素数。 例如,11,13均为真素数,因为11的反序还是为11,13的反序为31也为素数。 【输入】 输入两个数M和N,空...

Obey_bey_an的博客 2109

1007 素数对猜想 (20 分)

转自:https://blog.youkuaiyun.com/Simonqwer/article/details/114594633 #include<iostream> using namespace std; #include<iomanip> #include<algorithm> #include<string> #include<queue> #include<vector> #include<map> #include&lt

weixin_46631713的博客 101

Java、素数遍历器

【代码】Java、素数遍历器。

m0_62659797的博客 157

Prime Square(思维)

题意 t 组数据,每组数据有一个 n ,表示你要输出 n*n 的矩阵,而矩阵中的数字满足以下要求: 为 100000以内的非负整数 不能为素数 每列每行数字之和为素数 思路 分析: 如果一个一个去判断、去暴力,好复杂,可能还会超时。所以应该去简化一下判断的数量,如何做呢? 我们是否可以敲定每行每列的大部分数字,而只判断一个数字呢(也就是找特殊情况)?好像可以。 确定思路: 我们把 n-1 个数字确定为 1 ,那么现在每行每列的和就是 s=n-1 仅判断最后一个数字 k 的值(不能为素数) s + k

weixin_44091134的博客 567

Java求100000以内素数_100000以内的质数表

最近在PKU上面做题,发现好多题目都用到了质数表,于是干脆把100000以内的质数表和生成质数的程序贴上来好了,大家也好抄,直接用~~~ 嘿嘿……Program:#include #define N 100000int sieve[N + 1];void main(){for(int i = 2; i <= N; i++) sieve[i] = 1;for(i = 2; i <=...

weixin_31579367的博客 1266

100000以内素数java实验结果截图_生成100000以内的素数XML文件的Demo(Jdom写成)

搜索热词public class TestPrimeXml {private static String fileName = "Primes.xml";//获取源文件路径private static String path = System.getProperty("user.dir") + File.separator + "src" + File.separator + fileName;p...

weixin_31727937的博客 161

100000以内素数java实验结果截图_寻找100000以内素数(质数)

方法一简单的质数寻找就是对1~100000的数进行遍历方法二这样的遍历复杂度为O(n2)进行优化就可以发现偶数不可能为质数,因此质数也不可能含有偶数因子方法三经过计算发现所有的质数都满足4x+1或者4x-1因此将其命名为模4遍历法方法四与方法三类似,创建了模6遍历法以下是源代码import java.util.ArrayList;import java.util.List;/*** Author:...

weixin_35840528的博客 424

Java自学习day5-Java100000以内的所有质数的输出并进行优化

嵌套循环的应用1-九九乘法表 1 * 1 = 1 2 * 1 = 2 2 * 2 = 4 … 9 * 1 = 9 … … 9 * 9 = 81 class NineNineTable { public static void main(String[] args) { for(int i = 1;i <= 9;i++){ for(int j = 1;j <= i;j++){ System.out.print(i + " * " + j +

加油鸭 617
上一篇: shell编程(5)
下一篇: 判断素数
caoruntaogmail
博客等级 码龄18年 3粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值