这个程序是一个c ++程序,它使用eratosthenes筛来找到素数来计算质数。然后假设存储执行此操作所需的时间,并重新执行计算100次,每次存储时间。在这个程序中我需要帮助两件事:
首先,我只能测试高达4.8亿的数字,我想要比这更高。
其次,当我计算程序时,它只获得第一个时间,然后打印零作为时间。这是不正确的,我不知道时钟的问题是什么。 - 谢谢你的帮助
这是我的代码。
#include <iostream>
#include <ctime>
using namespace std;
int main ()
{
int long MAX_NUM = 1000000;
int long MAX_NUM_ARRAY = MAX_NUM+1;
int long sieve_prime = 2;
int time_store = 0;
while (time_store<=100)
{
int long sieve_prime_constant = 0;
int *Num_Array = new int[MAX_NUM_ARRAY];
std::fill_n(Num_Array, MAX_NUM_ARRAY, 3);
Num_Array [0] = 1;
Num_Array [1] = 1;
clock_t time1,time2;
time1 = clock();
while (sieve_prime_constant <= MAX_NUM_ARRAY)
{
if (Num_Array [sieve_prime_constant] == 1)
{
sieve_prime_constant++;
}
else
{
Num_Array [sieve_prime_constant] = 0;
sieve_prime=sieve_prime_constant;
while (sieve_prime<=MAX_NUM_ARRAY - sieve_prime_constant)
{
sieve_prime = sieve_prime + sieve_prime_constant;
Num_Array [sieve_prime] = 1;
}
if (sieve_prime_constant <= MAX_NUM_ARRAY)
{
sieve_prime_constant++;
sieve_prime = sieve_prime_constant;
}
}
}
time2 = clock();
delete[] Num_Array;
cout << "It took " << (float(time2 - time1)/(CLOCKS_PER_SEC)) << " seconds to execute this loop." << endl;
cout << "This loop has already been executed " << time_store << " times." << endl;
float Time_Array[100];
Time_Array[time_store] = (float(time2 - time1)/(CLOCKS_PER_SEC));
time_store++;
}
return 0;
}
答案 0 :(得分:0)
这部分代码应该进入你的循环:
int *Num_Array = new int[MAX_NUM_ARRAY];
std::fill_n(Num_Array, MAX_NUM_ARRAY, 3);
Num_Array [0] = 1;
Num_Array [1] = 1;
编辑:这个也需要在循环中:
int long sieve_prime_constant = 0;
当我在我的机器上运行它时,每个循环需要0.2秒。如果我向MAX_NUM_ARRAY添加两个零,则每次迭代需要4.6秒(直到第20个循环,我感到无聊等待超过1.5分钟)
答案 1 :(得分:0)
我认为问题在于你没有重置起始素数:
int long sieve_prime = 2;
目前,这不在您的循环中。再想一想......那不是问题。是否编辑了此代码以结合Mats Petersson的答案中的建议?我刚刚纠正了不好的缩进。
无论如何,对于问题的其他部分,我建议您使用char
代替int
Num_Array
。使用int
存储布尔值没有用处。通过使用char
,您应该能够在相同的内存量中存储大约4倍的值(假设您的int
是32位,它可能是)。
这意味着您可以处理近20亿的数字。由于您使用signed long
作为类型而不是unsigned long
,因此无论如何都要接近计算的数字限制。
如果您想使用更少的内存,可以使用std::bitset
,但要注意性能可能会受到严重影响。
顺便说一下,你应该在main
:
float Time_Array[100];
在使用它之前把它放在循环中有点麻烦。
哦,如果你感兴趣的话,这是我自己实施的筛子,我个人觉得比你的更容易阅读....
std::vector<char> isPrime( N, 1 );
for( int i = 2; i < N; i++ )
{
if( !isPrime[i] ) continue;
for( int x = i*2; x < N; x+=i ) isPrime[x] = 0;
}
答案 2 :(得分:0)
同意之前的评论。如果你真的想要榨汁,你不会存储所有可能值的数组(如int或char),但只保留素数。然后,通过到目前为止找到的所有素数,测试每个后续数字的可分性。现在,您只能受到可以存储的素数的限制。当然,这不是你想要实现的算法......但是因为它将使用整数除法,所以它非常快。像这样:
int myPrimes[MAX_PRIME];
int pCount, ii, jj;
ii = 3;
myPrimes[0]=2;
for(pCount=1; pCount<MAX_PRIME; pCount++) {
for(jj = 1; jj<pCount; jj++) {
if (ii%myPrimes[jj]==0) {
// not a prime
ii+=2; // never test even numbers...
jj = 1; // start loop again
}
}
myPrimes[pCount]=ii;
}
不是你要求的,但也许它很有用。