找质数算法(Sieve of Eratosthenes筛法)
2016-02-17 16:45
447 查看
由于一个合数总是可以分解成若干个质数的乘积,那么如果把质数(最初只知道2是质数)的倍数都去掉,那么剩下的就是质数了。
例如要查找100以内的质数,首先2是质数,把2的倍数去掉;此时3没有被去掉,可认为是质数,所以把3的倍数去掉;再到5,再到7,7之后呢,因为8,9,10刚才都被去掉了,而100以内的任意合数肯定都有一个因子小于10(100的开方),所以,去掉,2,3,5,7的倍数后剩下的都是质数了。
用程序可以这样解决,引入布尔类型数组a[i],如果i是质数,a[i]=true,否则a[i]=false。那么划掉i可以表示成a[i]=false。
//找出n以内质数
void Sieve(int n)
{
bool[] a = new bool[n+1];
for (int i = 2; i <= n; i++) a[i] = true;
for (int i = 2; i <= Math.Sqrt(n); i++)
{
if (a[i])
for (int j = i; j*i <= n; j++) a[j * i] = false;
}
for (int i = 0; i <= n; i++)
{
if (a[i])
Console.Write("{0},",i.ToString());
}
}
如果去掉最后一个用来显示结果的循环的话,运行Sieve(10000000)只要1秒多,而上次那个算法PrimeNum(10000000)却要71秒多!
/**
* Solves the challenge by utilizing a Sieve of Eratosthenes (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
*
* @param options
* @returns {number}
*/
getSolutionViaSieve = function (options) {
var upperBound = options.upperBound || 0,
primes = new Array(upperBound),
primeSum = 0;
// Initialize all of the numbers from zero to upper bound with a null value. Later, each index will be checked
// for null to see if it's been market yet.
for (var a=0; a<upperBound; a++) {
primes[a] = null;
}
// Iterate from the lowest prime (2) to upperBound to flag prime or not prime.
for (var i=2; i<upperBound; i++) {
// Only proceed if the current index hasn't been flagged as prime or not prime.
if (primes[i] === null) {
// Flag the current index as prime.
primes[i] = true;
// And flag any remaining multiples of this prime as not prime.
for (var j=i*i; j<upperBound; j+=i) {
primes[j] = false;
}
}
}
// Iterate and add up all primes.
for (var p=0; p<upperBound; p++) {
if (primes[p] === true) {
primeSum += p;
}
}
return primeSum;
};
console.log(getSolutionViaSieve({upperBound: 10}));
console.log(getSolutionViaSieve({upperBound: 2000000}));
例如要查找100以内的质数,首先2是质数,把2的倍数去掉;此时3没有被去掉,可认为是质数,所以把3的倍数去掉;再到5,再到7,7之后呢,因为8,9,10刚才都被去掉了,而100以内的任意合数肯定都有一个因子小于10(100的开方),所以,去掉,2,3,5,7的倍数后剩下的都是质数了。
用程序可以这样解决,引入布尔类型数组a[i],如果i是质数,a[i]=true,否则a[i]=false。那么划掉i可以表示成a[i]=false。
//找出n以内质数
void Sieve(int n)
{
bool[] a = new bool[n+1];
for (int i = 2; i <= n; i++) a[i] = true;
for (int i = 2; i <= Math.Sqrt(n); i++)
{
if (a[i])
for (int j = i; j*i <= n; j++) a[j * i] = false;
}
for (int i = 0; i <= n; i++)
{
if (a[i])
Console.Write("{0},",i.ToString());
}
}
如果去掉最后一个用来显示结果的循环的话,运行Sieve(10000000)只要1秒多,而上次那个算法PrimeNum(10000000)却要71秒多!
/**
* Solves the challenge by utilizing a Sieve of Eratosthenes (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
*
* @param options
* @returns {number}
*/
getSolutionViaSieve = function (options) {
var upperBound = options.upperBound || 0,
primes = new Array(upperBound),
primeSum = 0;
// Initialize all of the numbers from zero to upper bound with a null value. Later, each index will be checked
// for null to see if it's been market yet.
for (var a=0; a<upperBound; a++) {
primes[a] = null;
}
// Iterate from the lowest prime (2) to upperBound to flag prime or not prime.
for (var i=2; i<upperBound; i++) {
// Only proceed if the current index hasn't been flagged as prime or not prime.
if (primes[i] === null) {
// Flag the current index as prime.
primes[i] = true;
// And flag any remaining multiples of this prime as not prime.
for (var j=i*i; j<upperBound; j+=i) {
primes[j] = false;
}
}
}
// Iterate and add up all primes.
for (var p=0; p<upperBound; p++) {
if (primes[p] === true) {
primeSum += p;
}
}
return primeSum;
};
console.log(getSolutionViaSieve({upperBound: 10}));
console.log(getSolutionViaSieve({upperBound: 2000000}));
相关文章推荐
- 正则表达式的用法和常用正则表达式大全(转)
- slf4j+log4j配置
- Xcode7如何添加pch文件
- top 命令
- Get notification texts colors and background
- 利用html5 Api 实现分页
- android滚轮式时间选择器
- 1081. Rational Sum (20)
- view 加边框及颜色
- tomcat bin目录中的 startup.sh 双击闪退(win8)
- 第1章 错误处理
- Zoho Survey可以自动批卷啦
- Block很简单,就像delegate的简化版
- C语言 预处理二(宏定义--#define)
- Mybatis乱码问题_me
- javascript每日必学之条件分支
- Nginx简介(待编辑)
- 【Linux运维入门】Nexus索引更新和仓库迁移
- CEF中文教程(google chrome浏览器控件) -- CEF简介
- 数据结构