Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是一个低效率的主生成器C++;?_C++_Performance_Primes - Fatal编程技术网

C++ 这是一个低效率的主生成器C++;?

C++ 这是一个低效率的主生成器C++;?,c++,performance,primes,C++,Performance,Primes,这被看作是一个高效的素数生成器。在我看来,这是相当有效的。是流的使用使程序运行变慢了吗 我正试图提交给,它告诉我,我的时间限制超过了 #include <iostream> #include <sstream> using namespace std; int main() { int testCases, first, second, counter = 0; bool isPrime = true; stringstream out;

这被看作是一个高效的素数生成器。在我看来,这是相当有效的。是流的使用使程序运行变慢了吗

我正试图提交给,它告诉我,我的时间限制超过了

#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;
}
#包括
#包括
使用名称空间std;
int main(){
int测试用例,第一个,第二个,计数器=0;
bool isPrime=true;
流出来;
cin>>测试用例;
for(int i=0;i>第一>>第二;
如果(第一个%2==0)
第一++;
//找出两个给定数之间的素数
对于(int j=first;j这是简单算法之上的一个步骤(跳过偶数)。我建议将作为更有效的算法。从上面的链接:

算法的复杂度是 O((nlogn)(loglogn))与内存 O(n)的要求。分段 Eratosthenes筛的版本, 具有基本的优化功能,如车轮 因式分解,使用O(n)运算 和的O(n1/2logn/logn)位 记忆


你给出的算法在O(n^2)附近。跳过evens所获得的加速效果并不是很好,因为在第一次测试中,你会发现偶数不是素数。筛子的内存需求要大得多,但运行时的复杂性远远高于大N。你搜索的数字比你必须搜索的要多得多-最多只需转到
它可以是made的效率稍高一些。您不需要从2开始k,您已经确保不测试偶数。所以从3开始k。
然后每次将k增加2,因为不需要测试其他偶数。 我能想到的最有效的方法是只测试一个数是否可以被已知的素数整除(然后当你找到另一个素数时,将其添加到你测试的列表中)。

for(int k=2;k
应该是:

for(int k = 3; k <= j/2; k+=2 )
{
  if( j % k == 0 )
      break;
}

for(int k=3;k这里有一个简单的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;
}
#包括
#包括
使用名称空间std;
模板
类素数迭代器{
公众:
素数迭代器():当前(2),skips(){skips[4]=2;}
T运算符*(){返回电流;}
素数迭代器和运算符++(){
类型名M::迭代器i;
while((i=skips.find(++current))!=skips.end(){
T skip=i->second,next=current+skip;
跳过。删除(i);
for(typename M::iterator j=skips.find(next);
j!=skips.end();j=skips.find(next+=skip)){}
跳过[下一步]=跳过;
}
跳过[当前*当前]=当前;
归还*这个;
}
私人:
T电流;
M跳跃;
};
int main(){
素数迭代器素数;
对于(;*素数<1000;++素数)

cout还有一件事,不要在循环中使用sqrt(n):

for(int k=1;k<sqrt(n);++k)

用于(int k=1;k这在可用内存中可能是不可能的,但是;设置一个大小为int max的数组,然后取消未使用的项需要大量的RAM;当然可以用链表来完成,但是这很慢,Too你真的只需要每个数字一位就可以实现该算法。对于SPOJ,我怀疑他们会把第二位放在第一位内存太大将是一个问题,如果他们这样做了,他们可能会对运行时非常宽容。一般来说,SPOJ会强迫你选择一个运行时效率高(如果不是内存效率高的话)的算法来及时完成。这是真的吗?如果我需要找到介于1和9之间的素数,如果我只测试了3个,我怎么才能找到5和7呢因式分解的墨迹?他指的是在循环中2得到它的地方。那很尴尬;-)sqrt(j)即使j为100,也比j/2好得多。同样的想法,只有6k+1和6k+5可以是素数。+1非常好!但是…当看到素数时,你在地图中为素数的平方添加一个跳过值。在看到与该平方相等的候选值之前,这些信息将不需要。瞧,你只需要在地图中包含跳过值对于低于当前候选素数sqrt的素数。这将使其成为~O(sqrt(N))空间。另一件事是,
current*current
会导致任何高于46340的素数出错;因此,您的代码低于10 mil,而不是。
for(int k=1;k<sqrt(n);++k)
for (int k=1;k*k < n;++k)
int sq = sqrt ( n );
for (int k=1;k<sq;++k)