我编写了这段代码来显示1到100之间的素数。唯一的条件是不使用函数,整个代码应该是内联的。我会问我是否可以改进(优化)它?
#include<iostream>
using namespace std;
int main() {
int i=2,j=2;
cout<<"Prime numbers between 1 and 100 are:"<<endl;
cout<<"2"<<"\t";
while(i!=100) {
for(int j=2;j<i;j++) {
if(i%j==0)
break;
if(j==i-1)
cout<<i<<"\t";
}
i++;
}
cout<<endl;
system("pause");
return 0;
}
答案 0 :(得分:3)
for(int j=2;j<i;j++){
这个不太好。
首先,您只需要检查j <= sqrt(i)
,因为例如7不会在没有休息的情况下将12分开。
其次,你应该跟踪所有以前找到的素数;把它保存在向量中,只为我写的那个条件的内容和做这个循环。
答案 1 :(得分:3)
您可以优化现有代码:
您可以使用其他方法:
在Erastoses筛选中,只删除可分为2,3和5的数字会大大减少你需要测试素数的次数。
答案 2 :(得分:3)
避免使用平方根函数,并将除数递增2.还有一些棘手的事情在i循环中将你的可能素数递增2.内循环甚至不需要检验除数2,因为没有偶数将甚至进行测试。
int i,j,sq;
int min;
for(sq = 2; sq <= 10; sq++)
{
min = (sq-1)*(sq-1);
min = min + (min+1)%2; //skip if it's even, so we always start on odd
for(i = min; i < sq*sq; i+=2)
{
for(j = 3; j <= sq; j+=2)
{
if (i%j == 0)
bad;
}
}
}
请注意,sq循环不会增加时间,因为它会按比例缩小内部循环。
答案 3 :(得分:3)
如果你只想要低于100的素数,就没有必要编写代码来计算它们。这可能是一个愚蠢的答案,但它可以有效和简洁地解决您的问题。
int main() {
cout << "Prime numbers are:" << endl << "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" << endl;
return 0;
}
答案 4 :(得分:2)
您正在检查从2到100的每个数字。但由于2是唯一的偶数素数,因此您可以在2之后跳过每个偶数。这适用于i
和j
。所以从3开始i
和j
,然后将它们递增2。
#include<iostream>
using namespace std;
int main() {
cout<<"Prime numbers between 1 and 100 are:"<<endl;
cout<<"2"<<"\t";
for (int i=3; i<100;i+=2) {
// This loop stops either when j*j>i or when i is divisible by j.
// The first condition means prime, the second, not prime.
int j=3;
for(;j*j<=i && i%j!=0; j+=2); // No loop body
if (j*j>i) cout << i << "\t";
}
cout<<endl;
return 0;
}
除了上面提到的技巧之外,我还添加了条件j*j<=i
,它在逻辑上与j<=sqrt(i)
完全相同。当你可以做一个简单的乘法时,不需要计算平方根。
答案 5 :(得分:1)
取决于您希望进行的优化。如果你首先优化空间,时间第二(好吧,关闭 - 只要你听@Paul,它就会是),你可以看到你的优点。如果你颠倒了优先事项,Erastothenes的筛子会更快(但会占用你的记忆的100个布尔)。
答案 6 :(得分:1)
您可以做两个简单的优化:
cout << 2 << '\t';
for (int i = 3; i <= 100; ++i) {
for (int j = 3, l = (int)sqrt(i); j <= l; j += 2) {
if (i % j == 0) {
cout << i << '\t';
break;
}
}
我做了什么:
数学:
j > sqrt(i)
时停止,没有必要进一步发展。但请注意sqrt
是一项昂贵的功能;对于你的小样本(从1到100),它可能(读,肯定会)花费你更多的钱来使用它。j += 2
而不是逐个增加j
微优化:
++i
代替i++
;后者有一个临时变量,它存储i
的原始值;前者没有。'\t'
作为字符而不是字符串"\t"
。(这些微优化很可能是由编译器自动完成的,但了解它们并没有坏处。)
答案 7 :(得分:0)
实现这一目标的最有效方法是Eratosthenes筛选。这是一个增量版本,专门用于生成 100 的素数,逐个(最多 120 ,因为 121 == 11 * 11 )。
printf("2 ");
int m3=9, m5=25, m7=49, i=3;
for( ; i<100; i+=2 )
{
if( i!=m3 && i!=m5 && i!=m7) printf("%d ", i);
else
{
if( i==m3 ) m3+=6;
if( i==m5 ) m5+=10;
if( i==m7 ) m7+=14;
}
}
答案 8 :(得分:0)
/*** Return an array of primes from 2 to n. ***/
int[] function nPrimes(int n) {
int primes[]; //memory allocation may be necessary depending upon language.
int p = 0;
bool prime;
for (int i = 2; i <= n; i++) {
prime = true;
//use (j <= (int)sqrt(i)) instead of (j < i) for cost savings.
for (int j = 2; j <= (int)sqrt(i); j++) {
if (i % j == 0) {
prime = false;
break;
}
}
if (prime) {
primes[p++] = i;
}
}
return primes;
}