有没有办法让这个更优化..
#include <vector>
int main()
{
std::vector<int> primes;
primes.push_back(2);
for(int i=3; i < 100; i++)
{
bool prime=true;
for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++)
{
if(i % primes[j] == 0)
{
prime=false;
break;
}
}
if(prime)
{
primes.push_back(i);
cout << i << " ";
}
}
return 0;
}
答案 0 :(得分:11)
int main(int argc, char *argv[]) {
cout << "2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 ";
}
: - )
更严重的是,您可以通过缓存primes[j] * primes[j]
避免反复对质数进行平方并保存乘法。
答案 1 :(得分:4)
Sieve of Eratosthenes是一个很好的算法,用于生成一定数量的素数(这不是你的标题所说的,而是你的代码所暗示的。)
答案 2 :(得分:1)
是的,将i++
更改为i+=2
,它的效果会快两倍。
答案 3 :(得分:1)
primes[j]*primes[j] <= i
只检查primes[j] <= 7
i+=2
答案 4 :(得分:1)
是。正如Marion建议的那样,您可以使用Sieve of Eratosthenes,但您应该了解详细信息。你写的代码看起来像筛子,但事实并非如此。它被称为试验分裂,它与筛子有algorithmic complexity不同。
筛子执行传递,每个素数Theta(n/p)
需要p
次。这导致总复杂度为O(n log log n)
。 IIRC证明有点复杂,涉及prime number theorem。
您的算法为每个素数pi(sqrt(p))
执行p
除法,为非素数执行较少数量的除法。 (其中pi
是prime-counting function)。不幸的是,我无法想象出我头脑中的总体复杂性。
简而言之,您应该更改代码以使用数组并标记所有非素数。 This article解决了函数式编程语言中的相同主题。
答案 5 :(得分:1)
是的,Eratosthenes筛选是最佳选择(如果您需要超过100个数字this是最佳实施方案)。这是我的实施:
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
vector<int> sieve(int n){
vector<bool> prime(n+1,true);
vector<int> res;
prime[0]=prime[1]=false;
int m = (int)sqrt(n);
for(int i=2; i<=m; i++){
if(prime[i])
for(int k=i*i; k<=n; k+=i)
prime[k]=false;
}
for(int i=0; i<n ;i++)
if(prime[i])
res.push_back(i);
return res;
}
int main(){
vector<int> primes = sieve(100);
for(int i=0; i<primes.size() ;i++){
if(i) cout<<", ";
if(primes[i]) cout<<i;
}
cout<<endl;
}