这个素数生成器是不是效率低下的C++
Is this prime generator inefficient C++?
这被视为一个高效的素数生成器吗。在我看来,这是相当有效的。是流的使用使程序运行速度变慢了吗?
我正试图将此提交给SPOJ,它告诉我超过了时间限制。。。
#include <iostream>
#include <sstream>
using namespace std;
int main() {
int testCases, first, second, counter = 0;
bool isPrime = true;
stringstream out;
cin >> testCases;
for (int i = 0; i < testCases; i++) {
// get the next two numbers
cin >> first >> second;
if (first%2 == 0)
first++;
// find the prime numbers between the two given numbers
for (int j = first; j <= second; j+=2) {
// go through and check if j is prime
for (int k = 2; k < j; k++) {
if (j%k == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
out << j << "n";
}
isPrime = true;
}
out << "n";
}
cout << out.str();
return 0;
}
编辑:该程序应该在输入中指定的数字之间生成素数。(请参阅此处了解更多详细信息:Prime Generator问题)
-Tomek
这比朴素算法高出一步(跳过偶数)。我建议将埃拉托斯梯尼筛作为一种更有效的算法。从上面的链接:
算法的复杂性为O((nlogn)(loglogn))与内存O(n)的要求。分段的Eratosthenes筛的版本,具有基本优化功能,如车轮因式分解,使用O(n)运算以及记忆力
你给出的算法在O(n^2)附近。跳过偶数得到的加速并不是很好,因为你会发现偶数在第一次测试中不是素数。sive对内存的要求要高得多,但对于大型N,运行时的复杂性要高得多。
您搜索的数字比您必须搜索的要多,最多只需要转到<= (sqrt(num))
。
这里有一个简单的Eratosthenes筛。它不需要预先定义一个大的布尔数组,但它在时间和空间上仍然是>>O(n)。不过,只要你有足够的记忆力,它应该比你现在天真的方法快得多。
#include <iostream>
#include <map>
using namespace std;
template<typename T = int, typename M = map<T, T> >
class prime_iterator {
public:
prime_iterator() : current(2), skips() { skips[4] = 2; }
T operator*() { return current; }
prime_iterator &operator++() {
typename M::iterator i;
while ((i = skips.find(++current)) != skips.end()) {
T skip = i->second, next = current + skip;
skips.erase(i);
for (typename M::iterator j = skips.find(next);
j != skips.end(); j = skips.find(next += skip)) {}
skips[next] = skip;
}
skips[current * current] = current;
return *this;
}
private:
T current;
M skips;
};
int main() {
prime_iterator<int> primes;
for (; *primes < 1000; ++primes)
cout << *primes << endl;
return 0;
}
如果这对你来说仍然太慢,你可能想追求阿特金筛,一种优化的Eratosthenes筛。
实际上,只有当生成素数的范围开始较低时,这些方法才相对有效。如果下限已经相当大,而上限并没有比下限大多少,那么筛选方法就是浪费工作,你最好进行一次初选测试。
还有一件事,不要在循环中使用sqrt(n):
for(int k=1;k<sqrt(n);++k)
如果没有好的优化,那么每次迭代都会计算sqrt。
使用
for (int k=1;k*k < n;++k)
或者只是
int sq = sqrt ( n );
for (int k=1;k<sq;++k)
它可以稍微提高效率。你不需要从2开始k,你已经在确保不要测试偶数了。所以从3开始k。
然后每次将k增加2,因为你不需要测试其他偶数。我能想到的最有效的方法是只测试一个数字是否可以被已知素数整除(然后当你找到另一个素数时,把它加到你测试的列表中)。
for (int k = 2; k < j; k++) {
if (j%k == 0) {
isPrime = false;
break;
}
}
应该是:
for(int k = 3; k <= j/2; k+=2 )
{
if( j % k == 0 )
break;
}
j/2确实应该是sqrt(j),但它通常是一个足够好的估计。
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 代码的效率. 转到和函数调用
- 对于循环C++可能效率低下
- 内存效率表示最短路径的方法?
- 如何提高该函数的运行效率?
- 效率:标准::数组与标准::矢量
- 如何提高BST的搜索操作效率?
- 字符串引用参数的效率C++
- 提高基于组件的游戏引擎的效率
- 在 c++ 中使用带有映射的插入效率
- 关于效率的问题
- 在SQLITE数据库中写入记录需要花费大量时间.如何提高刀片操作效率?
- 寻求提高Microsoft密封库计算效率的方法
- 做对了一个类似竞争的问题,但需要帮助来提高效率
- C++ - 与 Numpy 中的矢量版本相比,Argsort 效率低的矢量版本实现
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- visual C++|循环效率
- 我创建了一个库,想知道设计是否效率低下
- 矩阵rowSums()与colSums(()在R与Rcpp与Armadillo中的效率
- 共享指针的复制和交换效率