求质数(Prime Number 素数)的方法——厄拉多塞筛法

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数即为素数。比1大但不是素数的数称为合数。1和0既非素数也非合数。合数是由若干个质数相乘而得到的。所以,质数是合数的基础,没有质数就没有合数。


【1】一般方法

素数是除了1和它本身之外再不能被其他数整除的自然数。由于找不到一个通项公式来表示所有的素数,所以对于数学家来说,素数一直是一个未解之谜。像著名的 哥德巴赫猜想、孪生素数猜想,几百年来不知吸引了世界上多少优秀的数学家。尽管他们苦心钻研,呕心沥血,但至今仍然未见分晓。
自从有了计算机之后,人们借助于计算机的威力,已经找到了2216091以内的所有素数。
求素数的方法有很多种,最简单的方法是根据素数的定义来求。对于一个自然数N,用大于1小于N的各个自然数都去除一下N,如果都除不尽,则N为素数,否则N为合数。
但是,如果用素数定义的方法来编制计算机程序,它的效率一定是非常低的,其中有许多地方都值得改进。
第一,对于一个自然数N,只要能被一个非1非自身的数整除,它就肯定不是素数,所以不
必再用其他的数去除。
第二,对于N来说,只需用小于N的素数去除就可以了。例如,如果N能被15整除,实际
上就能被3和5整除,如果N不能被3和5整除,那么N也决不会被15整除。
第三,对于N来说,不必用从2到N一1的所有素数去除,只需用小于等于√N(根号N)的所有素数去除就可以了。这一点可以用反证法来证明:
如果N是合数,则一定存在大于1小于N的整数d1和d2,使得N=d1×d2。
如果d1和d2均大于√N,则有:N=d1×d2>√N×√N=N。
而这是不可能的,所以,d1和d2中必有一个小于或等于√N。
基于上述分析,设计算法如下:
(1)用2,3,5,7逐个试除N的方法求出100以内的所有素数。
(2)用100以内的所有素数逐个试除的方法求出10000以内的素数。
首先,将2,3,5,7分别存放在a[1]、a[2]、a[3]、a[4]中,以后每求出一个素数,只要不大于100,就依次存放在A数组中的一个单元 中。当我们求100—10000之间的素数时,可依次用a[1]-a[2]的素数去试除N,这个范围内的素数可以不保存,直接打印。


【2】我们这里主要是讲解厄拉多塞筛法


简单介绍一下厄拉多塞筛法。厄拉多塞是一位古希腊数学家,他在寻找素数时,采用了一种与众不同的方法:先将2-N的各数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 N的素数。


这很像一面筛子,把满足条件的数留下来,把不满足条件的数筛掉。由于这种方法是厄拉多塞首先发明的,所以,后人就把这种方法称作厄拉多塞筛法。
在计算机中,筛法可以用给数组单元置零的方法来实现。具体来说就是:首先开一个数组:a[i],i=1,2,3,…,同时,令所有的数组元素都等于下标 值,即a[i]=i,当i不是素数时,令a[i]=0 。当输出结果时,只要判断a[i]是否等于零即可,如果a[i]=0,则令i=i+1,检查下一个a[i]。
筛法是计算机程序设计中常用的算法之一。

C++代码参考(求小于2000的素数):

#include "stdafx.h"
#include <iostream>

using namespace std;

#define N  2000

int _tmain(int argc, _TCHAR* argv[])
{

	int num[N];

	for (int i = 0; i < N; i++)
	{
		num[i] = i;
	}

	for (int j = 2; j < N; j++)
	{
		if(0 != num[j])
		{
			for (int k = 2; k*j < N; k++)
			{
				num[k*j] = 0;
			}
		}
	}

	for (int n = 0; n < N; n++)
	{
		if(0 != num[n])
		{
			cout<<" "<<num[n];
		}
	}

	cout<<endl;
	return 0;
}

【3】用6N±1法求素数。
任何一个自然数,总可以表示成为如下的形式之一:
6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…)
显然,当N≥1时,6N,6N+2,6N+3,6N+4都不是素数,只有形如6N+1和6N+5的自然数有可能是素数。所以,除了2和3之外,所有的素数都可以表示成6N±1的形式(N为自然数)。
根据上述分析,我们可以构造另一面筛子,只对形如6 N±1的自然数进行筛选,这样就可以大大减少筛选的次数,从而进一步提高程序的运行效率和速度。



与质数有关的猜想

哥德巴赫猜想

  哥德巴赫猜想(Goldbach Conjecture)大致可以分为两个猜想(前者称“强”或“二重哥德巴赫猜想”后者称“弱”或“三重哥德巴赫猜想”):1、每个不小于6的偶数都可以表示为两个奇素数之和;2、每个不小于9的奇数都可以表示为三个奇质数之和。
黎曼猜想
  黎曼猜想是一个困扰数学界多年的难题,最早由德国数学家波恩哈德·黎曼提出,迄今为止仍未有人给出一个令人完全信服的合理证明。即如何证明“关于质数的方程的所有意义的解都在一条直线上”。
  此条质数之规律内的质数月经过整形,“关于质数的方程的所有意义的解都在一条直线上”化为球体质数分布。
孪生质数猜想
  1849年,波林那克提出孪生质数猜想(the conjecture of twin primes),即猜测存在无穷多对孪生质数。
  猜想中的“孪生质数”是指一对质数,它们之间相差2。例如3和5,5和7,11和13,10016957和10016959等等都是孪生质数。
  10016957和10016959是发生在第333899位序号质数月的中旬[18±1]的孪生质数。
  质数月定位孪生质数发生位置:
  首个质数月孪生质数发生位置:[T-1]*30+【[4±1] [6±1] [12±1] [18±1] [30±1] 】 T=1
  其余质数月孪生质数发生位置:[T-1]*30+【[0±1] [12±1] [18±1] [30±1] 】 T=N是自然数代表质数月


多地转载,无法考究源地址,还请见谅。

筛法(线性筛,拉多) 在前前前前前前…的博客中,我们主要谈了欧拉筛和埃氏筛.今天我们主要来聊一聊线性筛和拉多(其实和埃氏筛和欧拉筛本质上没区别哎).其实在这两种筛法拉多筛最好懂(就连本蒟蒻一看代码就明白了…别看这个名字,容易糊弄人) 阅读详情

相关推荐

Python程序设计——拉多素数筛选法的应用

Python程序设计——拉多素数筛选法的应用

a15735748145a的博客 676

2021-10-08

拉多筛法 原理: 拉多筛法(Eratosthenes Sieve)是一种素数方法,也称之为标记法,由古希腊数学家拉多提出。 它的原理是:给定一个数 n,从 2 开始依次将 n 以内所有的数放入一个足够大的数组中(此时数组的所有赋值均为0),给数组中下标为素数的倍数数组值标记(1),标记完成后,剩余未被标记的数为素数(即数组素数下标里的值为0),此时我们只需要输出数组值为0的数组的下标就能得到2~n以内的素数。(素数是从 2 开始的,除了1和本身没有其他的公因数的数)。 0 0

yuyinxiSidney的博客 672

质数算法】——判断质数小于N的质数前N个质数

质数prime number)又称素数,一个大于1的自然数,除了1和它本身外,不能被其他自然数整除。 场景一:输入一个整数n,判断n是否为质数。 思路:判断是否大于或等于2,如果是则对遍历2到根号n区间的所有奇数取余是否为0,如果全都不是则为质数。事实上取余的区间可以更小,缩小为2到根号n区间的所有质数,但这以为着会牺牲空间记录下来,有得有失。目前最优的通用算法 代码实现(java) /

「Android之禅」公众号博主,和你分享有价值有思考的技术文章 4399

质数素数)的方法——拉多筛法(转载) ---2020.2.18

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数即为素数。比1大但不是素数的数称为合数。1和0既非素数也非合数。合数是由若干个质数相乘而得到的。所以,质数是合数的基础,没有质数就没有合数。 【1】一般方法 素数是除了1和它本身之外再不能被其他数整除的自然数。由于找不到一个通项公式来表示所有的素数,所以对于数学家来说...

Enoch-dj 1275

质数常见的几种方法

java质数的几种方法

gnsbxjj的博客 2082

LeetCode-204. 计数质数拉多筛法

目录 分析 204. 计数质数 分析 定义:质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。 最小的素数2,最小的合数是4。 判断一个数是不是质数有两种方法: (1)判断一个自然数是否是质数,我们只需从i=2到是否能整除n,因为一个合数的最小正因子一...

芝士不知世的笔记 392

LeetCode | 204. Count Primes 数论 素数筛选,拉多筛法

Count the number of prime numbers less than a non-negativenumber, n.Example:Input: 10Output: 4Explanation: There are 4 prime numbers less than10, they are 2, 3, 5, 7.这一题给你一个n,让你统计小于N的所有的素数的个数。假如按照传统的方...

u012737193的博客 533

matlab如何用prime质数,质数(Prime_Number)

一、定义质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。二、相关定理在一个大于1的数a和它2倍之间(即区间(a, 2a]中)必存在至少一个素数。存在任意长度的素数等差数列。(格林和陶哲轩,2004年)一个偶数可以写成两个数字之和,其中每一个数字都最多只有9个质因数。(挪...

weixin_39825854的博客 3459

(Leetcode) 计算质数 Count Primes - Python实现

题目: 统计所有小于非负整数n的质数的数量。Count the number of prime numbers less than a non-negative number,n. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 百度百科中关于质数的定义: 质数prime number)又称素数,定义为在大于1的自...

weixin_42077402的博客 540

Count Primes

题目链接 Count the number of prime numbers less than a non-negative number, n. Example: Input: 10 Output: 4 Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7. 看似不屑一顾的题目,却踩了大坑 pyth...

EmotionComputer 600

poj 2689 Prime Distance 筛法+区间筛素数

The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper fac

klc的博客 553

2Prime Number - 区间内素数(质数)的个数

问题如下: 判断101-200之间有多少个素数,并输出所有素数素数/质数的定义:只能被1或本身整除的数 所以一个数除以除了1与本身的数之外的数能除尽,则不是质数,思考了一下质数有这些:3 ,5 ,7,11,131 ...... 思路: 在区间素数个数时,对某一个未知类型的数,可以把它对2到它本身(1不用看了吧)的每一个数取模,模的尽则不为素数; 稍加思索,假设有c = a*b ...

Lazyafei's Blog 1531

【HDU 1016】Prime Ring Problem(DFS、素数)

思路: 要每两个相邻数之和都为素数,那么只要每次递归调用DFS时判断之前两个数之和是否为素数,另外注意因为是一个环,最后还要判断一下最后一个数和第一个数之和是否为素数。 程序开始时出一个素数数组,只需出50以内的素数即可,因为数据<20,最大的素数和为17+19=36。此处用的是素数筛法(什么是素数筛法?)素数素数筛法概览: 把从1开始的、某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉

Chen_yuazzy的博客 2254

素数(质数)prime number相关知识

1.判断一个数是否为素数 int prime(int x) { if(x==1) return 0;//不是素数 for(int i=2;i*i&lt;=x;i++) //i*i&lt;=n,用math.h了可以写为i&lt;=根号x { if(x%i==0) return 0; } return 1; } 2.素数打表 埃拉托斯特尼筛法-维基百科 借鉴的网友代...

月光酒馆 958

java 质数 prime number

需要我帮你把这篇内容排版成适配CSDN/简书的Markdown博文格式吗?若存在大于其平方根的因数,必然对应存在一个小于平方根的因数,因此只需遍历。:大于1的自然数,除了1和它本身之外,不存在其他可以整除它的正因数。即可完成校验,大幅减少循环次数。缺点:数据量大时效率极低。

2603_96324852的博客 214

c++ 判断是否为质数(素数 prime number)

#include <iostream> int main() { int n; std::cin >> n; if (n <= 1) std::cout << "not a prime number" << std::endl; else { int i; for ( i = 2; i <= sqrt(n); i++) { if (0 == n % i) break; } if ( i > sq

lishuangzhi的博客 1982

素數(Prime Number),亦称质数

素數(Prime Number),亦称质数,指在一個大於1的自然数中,除了1和此整数自身外,無法被其他自然数整除的数。換句話說,只有兩個正因数(1和自己)的自然数即為素數。比1大但不是素数的数称为合数。1和0既非素数也非合数。素数在数论中有着很重要的地位。目录[隐藏]1 關於素数 2 素数的數目 3 寻找素数 3.1 素數算法 4

2689
上一篇: 切忌在多线程中刷新界面
下一篇: 自定义输出宏替代NSLog
gavinming
博客等级 码龄18年 31粉丝 20原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值