C++ 我的埃拉托斯坦筛花的时间太长了
我已经实现了解决这个问题。虽然输出很好,但我的提交超过了时间限制。如何减少运行时间C++ 我的埃拉托斯坦筛花的时间太长了,c++,primes,sieve-of-eratosthenes,C++,Primes,Sieve Of Eratosthenes,我已经实现了解决这个问题。虽然输出很好,但我的提交超过了时间限制。如何减少运行时间 int main() { vector<int> prime_list; prime_list.push_back(2); vector<int>::iterator c; bool flag=true; unsigned int m,n; for(int i=3; i<=32000;i+=2) { flag=true; float s =
int main()
{
vector<int> prime_list;
prime_list.push_back(2);
vector<int>::iterator c;
bool flag=true;
unsigned int m,n;
for(int i=3; i<=32000;i+=2)
{
flag=true;
float s = sqrt(static_cast<float>(i));
for(c=prime_list.begin();c<=prime_list.end();c++)
{
if(*c>s)
break;
if(i%(*c)==0)
{
flag=false;
break;
}
}
if(flag==true)
{
prime_list.push_back(i);
}
}
int t;
cin>>t;
for (int times = 0; times < t; times++)
{
cin>> m >> n;
if (t) cout << endl;
if (m < 2)
m=2;
unsigned int j;
vector<unsigned int> req_list;
for(j=m;j<=n;j++)
{
req_list.push_back(j);
}
vector<unsigned int>::iterator k;
flag=true;
int p=0;
for(j=m;j<=n;j++)
{
flag=true;
float s = sqrt(static_cast<float>(j));
for(c=prime_list.begin();c<=prime_list.end();c++)
{
if((*c)!=j)
{
if((*c)>s)
break;
if(j%(*c)==0)
{
flag=false;
break;
}
}
}
if(flag==false)
{
req_list.erase (req_list.begin()+p);
p--;
}
p++;
}
for(k=req_list.begin();k<req_list.end();k++)
{
cout<<*k;
cout<<endl;
}
}
}
intmain()
{
向量素数表;
素数列表。推回(2);
向量::迭代器c;
布尔标志=真;
无符号整数m,n;
对于(int i=3;i>t;
对于(整数倍=0;倍>m>>n;
如果(t)不能分析代码,找到热点,消除它们,探查器链接。分析代码,找到热点,消除它们,探查器链接。我认为稍微加快筛选速度的一种方法是防止在这一行中使用mod操作符
如果(i%(*c)==0)
而不是(相对)昂贵的mod操作,也许如果你在你的筛中用加法向前迭代
老实说,我不知道这是否正确。如果没有注释和单字母变量名,您的代码很难阅读。我认为稍微加快筛选速度的一种方法是防止在这一行中使用mod运算符
如果(i%(*c)==0)
而不是(相对)昂贵的mod操作,也许如果你在你的筛中用加法向前迭代
老实说,我不知道这是否正确。如果没有注释和单字母变量名,您的代码很难阅读。我会抛开您的代码,从一个非常简单的筛选实现开始,如果真的需要,只会增加复杂性。以下是一个可能的起点:
#include <vector>
#include <iostream>
int main() {
int number = 32000;
std::vector<bool> sieve(number,false);
sieve[0] = true; // Not used for now,
sieve[1] = true; // but you'll probably need these later.
for(int i = 2; i<number; i++) {
if(!sieve[i]) {
std::cout << "\t" << i;
for (int temp = 2*i; temp<number; temp += i)
sieve[temp] = true;
}
}
return 0;
}
#包括
#包括
int main(){
整数=32000;
标准::向量筛(数字,假);
筛[0]=true;//暂时不使用,
sieve[1]=true;//但您以后可能需要这些。
对于(int i=2;i我会抛开你所拥有的,从一个真正简单的筛实现开始,如果真的需要,只会增加复杂性。这里有一个可能的起点:
#include <vector>
#include <iostream>
int main() {
int number = 32000;
std::vector<bool> sieve(number,false);
sieve[0] = true; // Not used for now,
sieve[1] = true; // but you'll probably need these later.
for(int i = 2; i<number; i++) {
if(!sieve[i]) {
std::cout << "\t" << i;
for (int temp = 2*i; temp<number; temp += i)
sieve[temp] = true;
}
}
return 0;
}
#包括
#包括
int main(){
整数=32000;
标准::向量筛(数字,假);
筛[0]=true;//暂时不使用,
sieve[1]=true;//但您以后可能需要这些。
对于(int i=2;i您的代码很慢,因为您没有实现Eratosthenes算法的筛选。该算法是这样工作的:
1) Create an array with size n-1, representing the numbers 2 to n, filling it with boolean values true (true means that the number is prime; do not forget we start counting from number 2 i.e. array[0] is the number 2)
2) Initialize array[0] = false.
3) Current_number = 2;
3) Iterate through the array by increasing the index by Current_number.
4) Search for the first number (except index 0) with true value.
5) Current_number = index + 2;
6) Continue steps 3-5 until search is finished.
该算法需要O(nloglogn)时间。
你所做的事情实际上需要更多的时间(O(n^2))。
顺便说一句,在第二步中(搜索n到m之间的素数),您不必再次检查这些数是否为素数,理想情况下,您将在算法的第一阶段计算它们
正如我在您链接的站点中看到的,主要问题是您无法实际创建大小为n-1的数组,因为最大数n为10^9,如果您以这种简单的方式创建,则会导致内存问题。此问题属于您:)您的代码很慢,因为您没有实现Eratosthenes算法的筛选。该算法是这样工作的:
1) Create an array with size n-1, representing the numbers 2 to n, filling it with boolean values true (true means that the number is prime; do not forget we start counting from number 2 i.e. array[0] is the number 2)
2) Initialize array[0] = false.
3) Current_number = 2;
3) Iterate through the array by increasing the index by Current_number.
4) Search for the first number (except index 0) with true value.
5) Current_number = index + 2;
6) Continue steps 3-5 until search is finished.
该算法需要O(nloglogn)时间。
你所做的事情实际上需要更多的时间(O(n^2))。
顺便说一句,在第二步中(搜索n到m之间的素数),您不必再次检查这些数是否为素数,理想情况下,您将在算法的第一阶段计算它们
正如我在您链接的站点中看到的,主要问题是您无法实际创建大小为n-1的数组,因为最大数n为10^9,如果您以这种简单的方式创建,则会导致内存问题。此问题属于您:)我不确定您是否实现了Erasthotenes筛选。无论如何,可以在一定程度上提高算法速度的两件事是:通过预分配空间避免向量内容的多次重新定位(查找std::vector::reserve
)。操作sqrt
成本很高,您可以通过修改测试(当x*x>y
而不是检查x
时停止)来完全避免该操作
然后,通过修改实际的算法,您将得到更好的改进。粗略地看,似乎您正在迭代所有候选项,并针对每一个候选项,尝试用可能是因子的所有已知素数进行除法。Erasthotenes的筛取单个素数,并在sin中丢弃该素数的所有倍数盖尔传球
请注意,筛子不会执行任何操作来测试某个数字是否为素数,如果在此之前未将其丢弃,则该数字为素数。对于每个唯一因子,每个非素数只访问一次。另一方面,您的算法会多次处理每个数(针对现有素数)我不确定您是否实现了Erasthotenes筛选。无论如何,可以在一定程度上提高算法速度的两件事是:通过预分配空间避免向量内容的多次重新定位(查找std::vector::reserve
)。操作sqrt
成本很高,您可以通过修改测试(当x*x>y
而不是检查x
时停止)来完全避免该操作
然后,通过修改实际的算法,您将得到更好的改进。粗略地看,似乎您正在迭代所有候选项,并针对每一个候选项,尝试用可能是因子的所有已知素数进行除法。Erasthotenes的筛取单个素数,并在sin中丢弃该素数的所有倍数盖尔传球
请注意,筛子不会执行任何操作来测试某个数字是否为素数,如果在此之前未将其丢弃,则该数字为素数。对于每个唯一因子,每个非素数只访问一次。另一方面,您的算法会多次处理每个数(针对现有素数)我对这个问题的理解是,必须生成[m,n]范围内的所有素数
一种不必计算[0,n]中所有素数的方法,因为这是mos